VBoxMPShgsmi.cpp revision 9055f61bb57d2a625c6434d55beac7565c3b3c0d
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* $Id$ */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** @file
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VBox WDDM Miniport driver
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Copyright (C) 2011 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
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncvoid vboxSHGSMICommandFree (struct _HGSMIHEAP * pHeap, PVBOXSHGSMIHEADER pCmd)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync HGSMIHeapFree (pHeap, pCmd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLINLINE(void) vboxSHGSMICommandRelease (struct _HGSMIHEAP * 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
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLCALLBACK(void) vboxSHGSMICompletionSetEvent(struct _HGSMIHEAP * pHeap, void *pvCmd, void *pvContext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTSemEventSignal((RTSEMEVENT)pvContext);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLCALLBACK(void) vboxSHGSMICompletionCommandRelease(struct _HGSMIHEAP * pHeap, void *pvCmd, void *pvContext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxSHGSMICommandRelease (pHeap, VBoxSHGSMIBufferHeader(pvCmd));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* do not wait for completion */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLINLINE(const VBOXSHGSMIHEADER*) vboxSHGSMICommandPrepAsynch (struct _HGSMIHEAP * pHeap, PVBOXSHGSMIHEADER pHeader)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* ensure the command is not removed until we're processing it */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxSHGSMICommandRetain(pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return pHeader;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLINLINE(void) vboxSHGSMICommandDoneAsynch (struct _HGSMIHEAP * 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
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncconst VBOXSHGSMIHEADER* VBoxSHGSMICommandPrepAsynchEvent (struct _HGSMIHEAP * 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
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncconst VBOXSHGSMIHEADER* VBoxSHGSMICommandPrepSynch (struct _HGSMIHEAP * 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
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncvoid VBoxSHGSMICommandDoneAsynch (struct _HGSMIHEAP * pHeap, const VBOXSHGSMIHEADER * pHeader)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxSHGSMICommandDoneAsynch(pHeap, pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncint VBoxSHGSMICommandDoneSynch (struct _HGSMIHEAP * 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
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncvoid VBoxSHGSMICommandCancelAsynch (struct _HGSMIHEAP * pHeap, const VBOXSHGSMIHEADER* pHeader)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxSHGSMICommandRelease(pHeap, (PVBOXSHGSMIHEADER)pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncvoid VBoxSHGSMICommandCancelSynch (struct _HGSMIHEAP * pHeap, const VBOXSHGSMIHEADER* pHeader)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBoxSHGSMICommandCancelAsynch (pHeap, pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTSEMEVENT hEventSem = (RTSEMEVENT)pHeader->u64Info2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTSemEventDestroy(hEventSem);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncconst VBOXSHGSMIHEADER* VBoxSHGSMICommandPrepAsynch (struct _HGSMIHEAP * 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
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncconst VBOXSHGSMIHEADER* VBoxSHGSMICommandPrepAsynchIrq (struct _HGSMIHEAP * 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
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncvoid* VBoxSHGSMICommandAlloc (struct _HGSMIHEAP * pHeap, HGSMISIZE cbData, uint8_t u8Channel, uint16_t u16ChannelInfo)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Issue the flush command. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXSHGSMIHEADER pHeader = (PVBOXSHGSMIHEADER)HGSMIHeapAlloc (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
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncvoid VBoxSHGSMICommandFree (struct _HGSMIHEAP * pHeap, void *pvBuffer)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXSHGSMIHEADER pHeader = VBoxSHGSMIBufferHeader(pvBuffer);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxSHGSMICommandRelease (pHeap, pHeader);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//int VBoxSHGSMISetup (PVBOXSHGSMIHEAP pHeap,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// void *pvBase,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// HGSMISIZE cbArea,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// HGSMIOFFSET offBase,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// bool fOffsetBased,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// PFNVBOXSHGSMINOTIFYHOST pfnNotifyHost,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// PFNVBOXSHGSMINOTIFYHOST pvNotifyHost)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// /* Setup a HGSMI heap within the adapter information area. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// return HGSMIHeapSetup (&pHeap->Heap,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// pvBuffer,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// cbBuffer,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// offBuffer,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// false /*fOffsetBased*/);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//int VBoxSHGSMIDestroy (PVBOXSHGSMIHEAP pHeap)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// HGSMIHeapDestroy (pHeap);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// return VINF_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define VBOXSHGSMI_CMD2LISTENTRY(_pCmd) ((PVBOXSHGSMILIST_ENTRY)&(_pCmd)->pvNext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define VBOXSHGSMI_LISTENTRY2CMD(_pEntry) ( (PVBOXSHGSMIHEADER)((uint8_t *)(_pEntry) - RT_OFFSETOF(VBOXSHGSMIHEADER, pvNext)) )
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncint VBoxSHGSMICommandProcessCompletion (struct _HGSMIHEAP * pHeap, VBOXSHGSMIHEADER* pCur, bool bIrq, PVBOXSHGSMILIST 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
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pfnCallback(pHeap, VBoxSHGSMIBufferData(pCur), pvCallback, &pfnCompletion, &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
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxSHGSMIListPut(pPostProcessList, VBOXSHGSMI_CMD2LISTENTRY(pCur), VBOXSHGSMI_CMD2LISTENTRY(pCur));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } while (0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return rc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncint VBoxSHGSMICommandPostprocessCompletion (struct _HGSMIHEAP * pHeap, PVBOXSHGSMILIST pPostProcessList)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXSHGSMILIST_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}