DevVGA_VDMA.cpp revision e2012d9a59c1ccf406e24122a327148f9c50009b
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg * Video DMA (VDMA) support.
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg * Copyright (C) 2006-2012 Oracle Corporation
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg * This file is part of VirtualBox Open Source Edition (OSE), as
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg * available from http://www.virtualbox.org. This file is free software;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg * you can redistribute it and/or modify it under the terms of the GNU
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg * General Public License (GPL) as published by the Free Software
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg * Foundation, in version 2 as it comes in the "COPYING" file of the
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg#define WARN_BP() do { } while (0)
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg } while (0)
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgtypedef struct VBOXVDMATHREAD
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg/* state transformations:
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg * submitter | processor
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg * LISTENING ---> PROCESSING
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg /* critical section for accessing ctl lists */
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgtypedef enum
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgtypedef DECLCALLBACKPTR(void, PFNVBVAEXHOSTCTL_COMPLETE)(VBVAEXHOSTCONTEXT *pVbva, struct VBVAEXHOSTCTL *pCtl, int rc, void *pvComplete);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgtypedef struct VBVAEXHOSTCTL
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg/* VBoxVBVAExHP**, i.e. processor functions, can NOT be called concurrently with each other,
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg * but can be called with other VBoxVBVAExS** (submitter) functions except Init/Start/Term aparently.
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg * Can only be called be the processor, i.e. the entity that acquired the processor state by direct or indirect call to the VBoxVBVAExHSCheckCommands
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg * see mor edetailed comments in headers for function definitions */
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgtypedef enum
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic VBVAEXHOST_DATA_TYPE VBoxVBVAExHPDataGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic void VBoxVBVAExHPDataCompleteCmd(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint32_t cbCmd);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic void VBoxVBVAExHPDataCompleteCtl(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL *pCtl, int rc);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg/* VBoxVBVAExHP**, i.e. processor functions, can NOT be called concurrently with each other,
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg * can be called concurrently with istelf as well as with other VBoxVBVAEx** functions except Init/Start/Term aparently */
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic int VBoxVBVAExHSCheckCommands(struct VBVAEXHOSTCONTEXT *pCmdVbva);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic int VBoxVBVAExHSInit(struct VBVAEXHOSTCONTEXT *pCmdVbva);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic int VBoxVBVAExHSEnable(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVABUFFER *pVBVA);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic int VBoxVBVAExHSDisable(struct VBVAEXHOSTCONTEXT *pCmdVbva);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic void VBoxVBVAExHSTerm(struct VBVAEXHOSTCONTEXT *pCmdVbva);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic int VBoxVBVAExHSSaveState(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic int VBoxVBVAExHSLoadState(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM, uint32_t u32Version);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic VBVAEXHOSTCTL* VBoxVBVAExHCtlAlloc(VBVAEXHOSTCONTEXT *pCmdVbva)
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg return (VBVAEXHOSTCTL*)RTMemCacheAlloc(pCmdVbva->CtlCache);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg return (VBVAEXHOSTCTL*)RTMemAlloc(sizeof (VBVAEXHOSTCTL));
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic void VBoxVBVAExHCtlFree(VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL *pCtl)
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic VBVAEXHOSTCTL* VBoxVBVAExHCtlCreate(VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL_TYPE enmType)
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic int vboxVBVAExHSProcessorAcquire(struct VBVAEXHOSTCONTEXT *pCmdVbva)
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg Assert(pCmdVbva->i32State >= VBVAEXHOSTCONTEXT_STATE_LISTENING);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg if (ASMAtomicCmpXchgS32(&pCmdVbva->i32State, VBVAEXHOSTCONTEXT_STATE_PROCESSING, VBVAEXHOSTCONTEXT_STATE_LISTENING))
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic VBVAEXHOSTCTL* vboxVBVAExHPCheckCtl(struct VBVAEXHOSTCONTEXT *pCmdVbva, bool *pfHostCtl, bool fHostOnlyMode)
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg Assert(pCmdVbva->i32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg if(!fHostOnlyMode && !ASMAtomicUoReadU32(&pCmdVbva->u32cCtls))
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg VBVAEXHOSTCTL* pCtl = RTListGetFirst(&pCmdVbva->HostCtlList, VBVAEXHOSTCTL, Node);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg if (ASMAtomicUoReadS32(&pCmdVbva->i32EnableState) > VBVAEXHOSTCONTEXT_ESTATE_PAUSED)
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg pCtl = RTListGetFirst(&pCmdVbva->GuestCtlList, VBVAEXHOSTCTL, Node);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg /* pCtl can not be null here since pCmdVbva->u32cCtls is not null,
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg * and there are no HostCtl commands*/
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic VBVAEXHOSTCTL* VBoxVBVAExHPCheckHostCtlOnDisable(struct VBVAEXHOSTCONTEXT *pCmdVbva)
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg return vboxVBVAExHPCheckCtl(pCmdVbva, &fHostCtl, true);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstatic bool vboxVBVAExHPCheckProcessCtlInternal(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL* pCtl)
static int vboxVBVAExHPCmdGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd)
return VINF_EOF;
return VINF_TRY_AGAIN;
if (!cbRecord)
return VINF_TRY_AGAIN;
return VINF_SUCCESS;
return VERR_INVALID_STATE;
static void VBoxVBVAExHPDataCompleteCtl(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL *pCtl, int rc)
static VBVAEXHOST_DATA_TYPE vboxVBVAExHPDataGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd)
bool fHostClt;
if (pCtl)
if (fHostClt)
return VBVAEXHOST_DATA_TYPE_HOSTCTL;
return VBVAEXHOST_DATA_TYPE_GUESTCTL;
return VBVAEXHOST_DATA_TYPE_NO_DATA;
switch (rc)
case VINF_SUCCESS:
return VBVAEXHOST_DATA_TYPE_CMD;
case VINF_EOF:
return VBVAEXHOST_DATA_TYPE_NO_DATA;
case VINF_TRY_AGAIN:
/* this is something really unexpected, i.e. most likely guest has written something incorrect to the VBVA buffer */
return VBVAEXHOST_DATA_TYPE_NO_DATA;
return VBVAEXHOST_DATA_TYPE_NO_DATA;
static VBVAEXHOST_DATA_TYPE VBoxVBVAExHPDataGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd)
/* we need to prevent racing between us clearing the flag and command check/submission thread, i.e.
* 5. ->here we need to re-check the queue state to ensure we do not leak the notification of the above command
return VBVAEXHOST_DATA_TYPE_NO_DATA;
return enmType;
if (pVBVA)
* VINF_SUCCESS - there are commands are in a queue, and the given thread is now the processor (i.e. typically it would delegate processing to a worker thread)
return VINF_SUCCESS;
return VINF_EOF;
return VINF_ALREADY_INITIALIZED;
return VERR_INVALID_STATE;
#ifndef VBOXVDBG_MEMCACHE_DISABLE
return VINF_SUCCESS;
#ifndef VBOXVDBG_MEMCACHE_DISABLE
return rc;
return VINF_ALREADY_INITIALIZED;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifndef VBOXVDBG_MEMCACHE_DISABLE
static int VBoxVBVAExHSSaveState(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM)
int rc;
return VERR_INVALID_STATE;
return VINF_SUCCESS;
return VINF_SUCCESS;
static int VBoxVBVAExHCtlSubmit(VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL* pCtl, VBVAEXHOSTCTL_SOURCE enmSource, PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
return VERR_INVALID_STATE;
return VERR_INVALID_STATE;
return rc;
static int VBoxVBVAExHSLoadState(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM, uint32_t u32Version)
return VINF_SUCCESS;
typedef struct VBOXVDMAHOST
#ifdef VBOX_VDMA_WITH_WATCHDOG
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
return rc;
rc = RTThreadCreate(&pThread->hWorkerThread, pfnThread, pvThread, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "VDMA");
return VINF_SUCCESS;
return rc;
return rc;
return rc;
int rc;
static int vdmaVBVACtlSubmitSync(PVBOXVDMAHOST pVdma, VBVAEXHOSTCTL* pCtl, VBVAEXHOSTCTL_SOURCE enmSource);
#ifdef VBOX_WITH_CRHGSMI
typedef DECLCALLBACK(void) FNVBOXVDMACRCTL_CALLBACK(PVGASTATE pVGAState, PVBOXVDMACMD_CHROMIUM_CTL pCmd, void* pvContext);
typedef struct VBOXVDMACMD_CHROMIUM_CTL_PRIVATE
void *pvCompletion;
#define VBOXVDMACMD_CHROMIUM_CTL_PRIVATE_FROM_CTL(_p) ((PVBOXVDMACMD_CHROMIUM_CTL_PRIVATE)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CTL_PRIVATE, Cmd)))
static PVBOXVDMACMD_CHROMIUM_CTL vboxVDMACrCtlCreate(VBOXVDMACMD_CHROMIUM_CTL_TYPE enmCmd, uint32_t cbCmd)
PVBOXVDMACMD_CHROMIUM_CTL_PRIVATE pHdr = (PVBOXVDMACMD_CHROMIUM_CTL_PRIVATE)RTMemAllocZ(cbCmd + RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CTL_PRIVATE, Cmd));
if (pHdr)
return NULL;
if(!cRefs)
static DECLCALLBACK(void) vboxVDMACrCtlCbSetEvent(PVGASTATE pVGAState, PVBOXVDMACMD_CHROMIUM_CTL pCmd, void* pvContext)
static DECLCALLBACK(void) vboxVDMACrCtlCbReleaseCmd(PVGASTATE pVGAState, PVBOXVDMACMD_CHROMIUM_CTL pCmd, void* pvContext)
static int vboxVDMACrCtlPostAsync (PVGASTATE pVGAState, PVBOXVDMACMD_CHROMIUM_CTL pCmd, uint32_t cbCmd, PFNVBOXVDMACRCTL_CALLBACK pfnCompletion, void *pvCompletion)
return VINF_SUCCESS;
#ifdef DEBUG_misha
Assert(0);
return VERR_NOT_SUPPORTED;
#ifdef DEBUG_misha
return rc;
typedef struct VDMA_VBVA_CTL_CYNC_COMPLETION
int rc;
static DECLCALLBACK(void) vboxVDMACrHgcmSubmitSyncCompletion(struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd, int rc, void *pvCompletion)
return rc;
rc = pVGAState->pDrv->pfnCrHgcmCtlSubmit(pVGAState->pDrv, pCtl, cbCtl, vboxVDMACrHgcmSubmitSyncCompletion, &Data);
return rc;
static DECLCALLBACK(VBOXCRCMDCTL*) vboxVDMACrHgcmHandleEnableRemainingHostCommand(HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hClient, uint32_t *pcbCtl, int prevCmdRc)
*pcbCtl = 0;
return NULL;
return VINF_SUCCESS;
return rc;
return VERR_INVALID_STATE;
if (!pVBVA)
return VERR_INVALID_PARAMETER;
#ifdef DEBUG_misha
return VERR_NOT_SUPPORTED;
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
return rc;
return rc;
return VERR_INVALID_STATE;
return VERR_INVALID_STATE;
return pVdma->CrSrvInfo.pfnLoadState(pVdma->CrSrvInfo.hSvr, pCmd->u.state.pSSM, pCmd->u.state.u32Version);
return VERR_INVALID_STATE;
return rc;
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_STATE;
return VERR_INVALID_PARAMETER;
return VINF_EOF;
if (!ASMAtomicCmpXchgU8(&pCmd->u8State, VBOXCMDVBVA_STATE_IN_PROGRESS, VBOXCMDVBVA_STATE_SUBMITTED))
return VINF_EOF;
return VINF_EOF;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_NOT_SUPPORTED;
static DECLCALLBACK(int) vboxVDMACrCmdCmd(HVBOXCRCMDSVR hSvr, PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
return VINF_SUCCESS;
if (pCmd)
return rc;
static int vboxVDMACmdExecBpbTransfer(PVBOXVDMAHOST pVdma, const PVBOXVDMACMD_DMA_BPB_TRANSFER pTransfer, uint32_t cbBuffer);
static int vboxVDMACmdCheckCrCmd(struct VBOXVDMAHOST *pVdma, PVBOXVDMACBUF_DR pCmdDr, uint32_t cbCmdDr)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
if (pDmaCmd)
return VERR_INVALID_PARAMETER;
Assert(0);
return VERR_INVALID_PARAMETER;
return rc;
int vboxVDMACrHgsmiCommandCompleteAsync(PPDMIDISPLAYVBVACALLBACKS pInterface, PVBOXVDMACMD_CHROMIUM_CMD pCmd, int rc)
return rc;
int vboxVDMACrHgsmiControlCompleteAsync(PPDMIDISPLAYVBVACALLBACKS pInterface, PVBOXVDMACMD_CHROMIUM_CTL pCmd, int rc)
return VINF_SUCCESS;
#ifdef VBOX_VDMA_WITH_WORKERTHREAD
/* to simplify things and to avoid extra backend if modifications we assume the VBOXVDMA_RECTL is the same as VBVACMDHDR */
static int vboxVDMANotifyPrimaryUpdate (PVGASTATE pVGAState, unsigned uScreenId, const VBOXVDMA_RECTL * pRectl)
sizeof (VBOXVDMA_RECTL));
return VINF_SUCCESS;
return VERR_INVALID_FUNCTION;
uint32_t offDstLineEnd = ((pDstRectl->left * pDstDesc->bpp + 7) >> 3) + ((pDstDesc->bpp * pDstRectl->width + 7) >> 3);
uint32_t offSrcLineEnd = ((pSrcRectl->left * pSrcDesc->bpp + 7) >> 3) + ((pSrcDesc->bpp * pSrcRectl->width + 7) >> 3);
for (uint32_t i = 0; ; ++i)
return VINF_SUCCESS;
static int vboxVDMACmdExecBlt(PVBOXVDMAHOST pVdma, const PVBOXVDMACMD_DMA_PRESENT_BLT pBlt, uint32_t cbBuffer)
const uint32_t cbBlt = VBOXVDMACMD_BODY_FIELD_OFFSET(uint32_t, VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects[pBlt->cDstSubRects]);
return VERR_INVALID_FUNCTION;
return VERR_INVALID_FUNCTION;
return VERR_INVALID_FUNCTION;
return rc;
return rc;
#ifdef VBOX_VDMA_WITH_WORKERTHREAD
int iView = 0;
return cbBlt;
static int vboxVDMACmdExecBpbTransfer(PVBOXVDMAHOST pVdma, const PVBOXVDMACMD_DMA_BPB_TRANSFER pTransfer, uint32_t cbBuffer)
return VERR_INVALID_PARAMETER;
const void * pvSrc;
void * pvDst;
bool bSrcLocked = false;
bool bDstLocked = false;
bSrcLocked = true;
bDstLocked = true;
if (bSrcLocked)
if (bDstLocked)
} while (cbTransfer);
return sizeof (*pTransfer);
return rc;
if (!pvBuffer)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
#ifdef VBOXWDDM_TEST_UHGSMI
static int count = 0;
if (count==0)
++count;
return VINF_SUCCESS;
if (cbBlt >= 0)
return VINF_SUCCESS;
const PVBOXVDMACMD_DMA_BPB_TRANSFER pTransfer = VBOXVDMACMD_BODY(pCmd, VBOXVDMACMD_DMA_BPB_TRANSFER);
if (cbTransfer >= 0)
return VINF_SUCCESS;
case VBOXVDMACMD_TYPE_DMA_NOP:
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_INVALID_FUNCTION;
return VERR_INVALID_STATE;
return rc;
switch (enmType)
case VBVAEXHOST_DATA_TYPE_CMD:
return VINF_SUCCESS;
int rc;
bool bReleaseLocked = false;
const void * pvPageBuf;
bReleaseLocked = true;
if (bReleaseLocked)
#ifdef VBOX_VDMA_WITH_WATCHDOG
if (cMillis)
return VINF_SUCCESS;
int rc;
#ifdef VBOX_VDMA_WITH_WORKERTHREAD
PVBOXVDMAHOST pVdma = (PVBOXVDMAHOST)RTMemAllocZ(RT_OFFSETOF(VBOXVDMAHOST, CmdPool.aCmds[cPipeElements]));
if (pVdma)
#ifdef VBOX_VDMA_WITH_WATCHDOG
#ifdef VBOX_WITH_CRHGSMI
int rcIgnored = vboxVDMACrCtlHgsmiSetup(pVdma); NOREF(rcIgnored); /** @todo is this ignoring intentional? */
return VINF_SUCCESS;
return rc;
return rc;
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
#ifdef VBOX_WITH_CRHGSMI
if (pCmd)
return rc;
return VERR_NO_MEMORY;
return VINF_SUCCESS;
#ifdef VBOX_WITH_CRHGSMI
if (pCmd)
return rc;
return VERR_NO_MEMORY;
return VINF_SUCCESS;
case VBOXVDMA_CTL_TYPE_ENABLE:
case VBOXVDMA_CTL_TYPE_FLUSH:
#ifdef VBOX_VDMA_WITH_WATCHDOG
#ifdef VBOX_WITH_CRHGSMI
/* chromium commands are processed by crhomium hgcm thread independently from our internal cmd processing pipeline
#ifndef VBOX_VDMA_WITH_WORKERTHREAD
# ifdef DEBUG_misha
Assert(0);
static int vdmaVBVACtlSubmit(PVBOXVDMAHOST pVdma, VBVAEXHOSTCTL* pCtl, VBVAEXHOSTCTL_SOURCE enmSource, PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
return rc;
static DECLCALLBACK(void) vboxCmdVBVACmdCtlGuestCompletion(VBVAEXHOSTCONTEXT *pVbva, struct VBVAEXHOSTCTL *pCtl, int rc, void *pvContext)
static int vdmaVBVACtlOpaqueSubmit(PVBOXVDMAHOST pVdma, VBVAEXHOSTCTL_SOURCE enmSource, uint8_t* pu8Cmd, uint32_t cbCmd, PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
if (!pHCtl)
return VERR_NO_MEMORY;
return rc;;
return VINF_SUCCESS;
int rc = vdmaVBVACtlOpaqueSubmit(pVdma, VBVAEXHOSTCTL_SOURCE_GUEST, (uint8_t*)(pCtl+1), cbCtl - sizeof (VBOXCMDVBVA_CTL), vboxCmdVBVACmdCtlGuestCompletion, pVdma);
return VINF_SUCCESS;
return VINF_SUCCESS;
static DECLCALLBACK(void) vboxCmdVBVACmdCtlHostCompletion(VBVAEXHOSTCONTEXT *pVbva, struct VBVAEXHOSTCTL *pCtl, int rc, void *pvCompletion)
static int vdmaVBVACtlOpaqueHostSubmit(PVBOXVDMAHOST pVdma, struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd,
void *pvCompletion)
int rc = vdmaVBVACtlOpaqueSubmit(pVdma, VBVAEXHOSTCTL_SOURCE_HOST_ENABLED, (uint8_t*)pCmd, cbCmd, vboxCmdVBVACmdCtlHostCompletion, pvCompletion);
rc = pVGAState->pDrv->pfnCrHgcmCtlSubmit(pVGAState->pDrv, pCmd, cbCmd, pfnCompletion, pvCompletion);
return rc;
return rc;
return VINF_SUCCESS;
static int vdmaVBVACtlEnableDisableSubmitInternal(PVBOXVDMAHOST pVdma, VBOXCMDVBVA_CTL_ENABLE *pEnable, PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
if (!pHCtl)
return VERR_NO_MEMORY;
return rc;;
return VINF_SUCCESS;
int rc = vdmaVBVACtlEnableDisableSubmitInternal(pVdma, pEnable, vboxCmdVBVACmdCtlGuestCompletion, pVdma);
return VINF_SUCCESS;
return VINF_SUCCESS;
static DECLCALLBACK(void) vdmaVBVACtlSubmitSyncCompletion(VBVAEXHOSTCONTEXT *pVbva, struct VBVAEXHOSTCTL *pCtl, int rc, void *pvContext)
static int vdmaVBVACtlSubmitSync(PVBOXVDMAHOST pVdma, VBVAEXHOSTCTL* pCtl, VBVAEXHOSTCTL_SOURCE enmSource)
return rc;
return rc;
switch (rc)
case VINF_SUCCESS:
case VINF_ALREADY_INITIALIZED:
case VINF_EOF:
case VERR_INVALID_STATE:
return VINF_SUCCESS;
void *pvCompletion)
return VINF_SUCCESS;
return VERR_INVALID_STATE;
return VERR_INVALID_STATE;