PDMDriver.cpp revision a9d49c8f2b28a72e6a4db86eee91e4569290157b
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * PDM - Pluggable Device and Driver Manager, Driver parts.
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * Copyright (C) 2006-2007 Sun Microsystems, Inc.
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * This file is part of VirtualBox Open Source Edition (OSE), as
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * available from http://www.virtualbox.org. This file is free software;
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * you can redistribute it and/or modify it under the terms of the GNU
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * General Public License (GPL) as published by the Free Software
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * Foundation, in version 2 as it comes in the "COPYING" file of the
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * Clara, CA 95054 USA or visit http://www.sun.com if you need
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * additional information or have any questions.
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering/*******************************************************************************
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering* Header Files *
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering*******************************************************************************/
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering/*******************************************************************************
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering* Structures and Typedefs *
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering*******************************************************************************/
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * Internal callback structure pointer.
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * The main purpose is to define the extra data we associate
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * with PDMDRVREGCB so we can find the VM instance and so on.
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering /** The callback structure. */
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering /** A bit of padding. */
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering /** VM Handle. */
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poetteringtypedef const PDMDRVREGCBINT *PCPDMDRVREGCBINT;
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering/*******************************************************************************
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering* Internal Functions *
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering*******************************************************************************/
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering/** @def PDMDRV_ASSERT_DRVINS
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * Asserts the validity of the driver instance.
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering Assert(pDrvIns->u32Version == PDM_DRVINS_VERSION); \
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering Assert(pDrvIns->pvInstanceDataR3 == (void *)&pDrvIns->achInstanceData[0]); \
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering# define PDMDRV_ASSERT_DRVINS(pDrvIns) do { } while (0)
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poetteringstatic DECLCALLBACK(int) pdmR3DrvRegister(PCPDMDRVREGCB pCallbacks, PCPDMDRVREG pDrvReg);
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poetteringstatic int pdmR3DrvLoad(PVM pVM, PPDMDRVREGCBINT pRegCB, const char *pszFilename, const char *pszName);
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * Register external drivers
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * @returns VBox status code.
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * @param pVM The VM to operate on.
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * @param pfnCallback Driver registration callback
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart PoetteringVMMR3DECL(int) PDMR3RegisterDrivers(PVM pVM, FNPDMVBOXDRIVERSREGISTER pfnCallback)
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * The registration callbacks.
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering RegCB.Core.u32Version = PDM_DRVREG_CB_VERSION;
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering RegCB.Core.pfnRegister = pdmR3DrvRegister;
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering int rc = pfnCallback(&RegCB.Core, VBOX_VERSION);
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering AssertMsgFailed(("VBoxDriversRegister failed with rc=%Rrc\n"));
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * This function will initialize the drivers for this VM instance.
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * First of all this mean loading the builtin drivers and letting them
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * register themselves. Beyond that any additional driver modules are
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * loaded and called for registration.
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * @returns VBox status code.
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * @param pVM VM Handle.
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering AssertRelease(!(RT_OFFSETOF(PDMDRVINS, achInstanceData) & 15));
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering AssertRelease(sizeof(pDrvInsAssert->Internal.s) <= sizeof(pDrvInsAssert->Internal.padding));
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * The registration callbacks.
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering RegCB.Core.u32Version = PDM_DRVREG_CB_VERSION;
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering RegCB.Core.pfnRegister = pdmR3DrvRegister;
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * Load the builtin module
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering PCFGMNODE pDriversNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM/Drivers");
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering int rc = CFGMR3QueryBool(pDriversNode, "LoadBuiltin", &fLoadBuiltin);
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering AssertMsgFailed(("Configuration error: Querying boolean \"LoadBuiltin\" failed with %Rrc\n", rc));
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering /* make filename */
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering char *pszFilename = pdmR3FileR3("VBoxDD", /*fShared=*/true);
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering rc = pdmR3DrvLoad(pVM, &RegCB, pszFilename, "VBoxDD");
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering * Load additional driver modules.
7732f92bad5f24a4bd03bb357af46da56b0ac94dLennart Poettering for (PCFGMNODE pCur = CFGMR3GetFirstChild(pDriversNode); pCur; pCur = CFGMR3GetNextChild(pCur))
AssertMsgFailed(("configuration error: The module name is too long, cchName=%zu.\n", CFGMR3GetNameLen(pCur)));
return VERR_PDM_MODULE_NAME_TOO_LONG;
return rc;
return rc;
if (!psz)
return VERR_NO_TMP_MEMORY;
return VERR_FILENAME_TOO_LONG;
return rc;
return VINF_SUCCESS;
static int pdmR3DrvLoad(PVM pVM, PPDMDRVREGCBINT pRegCB, const char *pszFilename, const char *pszName)
Log(("PDM: Calling VBoxDriversRegister (%p) of %s (%s)\n", pfnVBoxDriversRegister, pszName, pszFilename));
AssertMsgFailed(("Failed to locate 'VBoxDriversRegister' in %s (%s) rc=%Rrc\n", pszName, pszFilename, rc));
return rc;
AssertMsgReturn(pDrvReg->u32Version == PDM_DRVREG_VERSION, ("%#x\n", pDrvReg->u32Version), VERR_PDM_UNKNOWN_DRVREG_VERSION);
AssertMsgReturn((pDrvReg->fFlags & PDM_DRVREG_FLAGS_HOST_BITS_MASK) == PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
AssertMsgReturn(pDrvReg->cMaxInstances > 0, ("%s: %#x\n", pDrvReg->szDriverName, pDrvReg->cMaxInstances),
AssertMsgReturn(pDrvReg->cbInstance <= _1M, ("%s: %#x\n", pDrvReg->szDriverName, pDrvReg->cbInstance),
AssertMsgReturn(VALID_PTR(pDrvReg->pfnConstruct), ("%s: %p\n", pDrvReg->szDriverName, pDrvReg->pfnConstruct),
AssertMsgReturn(pDrvReg->pfnSoftReset == NULL, ("%s: %p\n", pDrvReg->szDriverName, pDrvReg->pfnSoftReset),
AssertMsgReturn(pDrvReg->u32VersionEnd == PDM_DRVREG_VERSION, ("%s: #x\n", pDrvReg->szDriverName, pDrvReg->u32VersionEnd),
return VERR_PDM_DRIVER_NAME_CLASH;
if (pDrv)
if (pDrvPrev)
return VINF_SUCCESS;
return VERR_NO_MEMORY;
return pDrv;
return NULL;
char *pszName;
if ( pDrv
if (!pConfigNode)
if (fHyperHeap)
if (pNew)
//pNew->Internal.s.pDown = NULL;
//pNew->Internal.s.fDetaching = false;
//pNew->Internal.s.fVMReset = false;
//pNew->Internal.s.pfnAsyncNotify = NULL;
if (pDrvAbove)
else if (pLun)
if (pLun)
if (pLun)
pDrvAbove, pDrvAbove ? pDrvAbove->pDrvReg->szDriverName : "", pDrvAbove ? pDrvAbove->iInstance : -1));
pDrvAbove, pDrvAbove ? pDrvAbove->pDrvReg->szDriverName : "", pDrvAbove ? pDrvAbove->iInstance : -1));
else if (pDrv)
AssertMsgFailed(("Too many instances of driver '%s', max is %u\n", pszName, pDrv->pDrvReg->cMaxInstances));
return rc;
LogFlow(("pdmR3DrvDetach: pDrvIns=%p '%s'/%d\n", pDrvIns, pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance));
AssertMsgFailed(("Recursive detach! '%s'/%d\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance));
return VINF_SUCCESS; }
AssertMsgFailed(("Cannot detach driver instance because the driver/device above doesn't support it!\n"));
return VINF_SUCCESS;
LogFlow(("pdmR3DrvDestroyChain: pCur=%p '%s'/%d\n", pCur, pCur->pDrvReg->szDriverName, pCur->iInstance));
if (fHyperHeap)
static DECLCALLBACK(int) pdmR3DrvHlp_Attach(PPDMDRVINS pDrvIns, uint32_t fFlags, PPDMIBASE *ppBaseInterface)
LogFlow(("pdmR3DrvHlp_Attach: caller='%s'/%d: fFlags=%#x\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, fFlags));
int rc;
if (pNode)
rc = pdmR3DrvInstantiate(pVM, pNode, &pDrvIns->IBase, pDrvIns, pDrvIns->Internal.s.pLun, ppBaseInterface);
return rc;
int rc;
return rc;
return rc;
static DECLCALLBACK(int) pdmR3DrvHlp_MountPrepare(PPDMDRVINS pDrvIns, const char *pszFilename, const char *pszCoreDriver)
pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, pszFilename, pszFilename, pszCoreDriver, pszCoreDriver));
return VERR_PDM_DRIVER_ALREADY_ATTACHED;
if (pNode)
if (!pszCoreDriver)
return VERR_NOT_IMPLEMENTED;
return rc;
return rc;
static DECLCALLBACK(bool) pdmR3DrvHlp_AssertEMT(PPDMDRVINS pDrvIns, const char *pszFile, unsigned iLine, const char *pszFunction)
RTStrPrintf(szMsg, sizeof(szMsg), "AssertEMT '%s'/%d\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance);
static DECLCALLBACK(bool) pdmR3DrvHlp_AssertOther(PPDMDRVINS pDrvIns, const char *pszFile, unsigned iLine, const char *pszFunction)
RTStrPrintf(szMsg, sizeof(szMsg), "AssertOther '%s'/%d\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance);
static DECLCALLBACK(int) pdmR3DrvHlp_VMSetError(PPDMDRVINS pDrvIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
int rc2 = VMSetErrorV(pDrvIns->Internal.s.pVMR3, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
return rc;
static DECLCALLBACK(int) pdmR3DrvHlp_VMSetErrorV(PPDMDRVINS pDrvIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
int rc2 = VMSetErrorV(pDrvIns->Internal.s.pVMR3, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
return rc;
static DECLCALLBACK(int) pdmR3DrvHlp_VMSetRuntimeError(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
return rc;
static DECLCALLBACK(int) pdmR3DrvHlp_VMSetRuntimeErrorV(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va)
return rc;
LogFlow(("pdmR3DrvHlp_VMState: caller='%s'/%d: returns %d (%s)\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance,
return enmVMState;
LogFlow(("pdmR3DrvHlp_VMState: caller='%s'/%d: returns %RTbool)\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance,
fRc));
return fRc;
static DECLCALLBACK(int) pdmR3DrvHlp_PDMQueueCreate(PPDMDRVINS pDrvIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval,
LogFlow(("pdmR3DrvHlp_PDMQueueCreate: caller='%s'/%d: cbItem=%d cItems=%d cMilliesInterval=%d pfnCallback=%p pszName=%p:{%s} ppQueue=%p\n",
pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, cbItem, cItems, cMilliesInterval, pfnCallback, pszName, pszName, ppQueue, ppQueue));
int rc = PDMR3QueueCreateDriver(pVM, pDrvIns, cbItem, cItems, cMilliesInterval, pfnCallback, pszName, ppQueue);
LogFlow(("pdmR3DrvHlp_PDMQueueCreate: caller='%s'/%d: returns %Rrc *ppQueue=%p\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, rc, *ppQueue));
return rc;
static DECLCALLBACK(int) pdmR3DrvHlp_TMTimerCreate(PPDMDRVINS pDrvIns, TMCLOCK enmClock, PFNTMTIMERDRV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
LogFlow(("pdmR3DrvHlp_TMTimerCreate: caller='%s'/%d: enmClock=%d pfnCallback=%p pvUser=%p fFlags=%#x pszDesc=%p:{%s} ppTimer=%p\n",
pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, enmClock, pfnCallback, pvUser, fFlags, pszDesc, pszDesc, ppTimer));
int rc = TMR3TimerCreateDriver(pDrvIns->Internal.s.pVMR3, pDrvIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
LogFlow(("pdmR3DrvHlp_TMTimerCreate: caller='%s'/%d: returns %Rrc *ppTimer=%p\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, rc, *ppTimer));
return rc;
static DECLCALLBACK(int) pdmR3DrvHlp_SSMRegister(PPDMDRVINS pDrvIns, uint32_t uVersion, size_t cbGuess,
" pfnLivePrep=%p pfnLiveExec=%p pfnLiveVote=%p pfnSavePrep=%p pfnSaveExec=%p pfnSaveDone=%p pszLoadPrep=%p pfnLoadExec=%p pfnLoaddone=%p\n",
int rc = SSMR3RegisterDriver(pDrvIns->Internal.s.pVMR3, pDrvIns, pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance,
LogFlow(("pdmR3DrvHlp_SSMRegister: caller='%s'/%d: returns %Rrc\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, rc));
return rc;
static DECLCALLBACK(int) pdmR3DrvHlp_SSMDeregister(PPDMDRVINS pDrvIns, const char *pszName, uint32_t u32Instance)
LogFlow(("pdmR3DrvHlp_SSMDeregister: caller='%s'/%d: returns %Rrc\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, rc));
return rc;
static DECLCALLBACK(void) pdmR3DrvHlp_STAMRegister(PPDMDRVINS pDrvIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
/** @todo track the samples so they can be dumped & deregistered when the driver instance is destroyed.
static DECLCALLBACK(void) pdmR3DrvHlp_STAMRegisterF(PPDMDRVINS pDrvIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
int rc = STAMR3RegisterV(pDrvIns->Internal.s.pVMR3, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args);
static DECLCALLBACK(void) pdmR3DrvHlp_STAMRegisterV(PPDMDRVINS pDrvIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
int rc = STAMR3RegisterV(pDrvIns->Internal.s.pVMR3, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args);
return rc;
static DECLCALLBACK(int) pdmR3DrvHlp_SUPCallVMMR0Ex(PPDMDRVINS pDrvIns, unsigned uOperation, void *pvArg, unsigned cbArg)
int rc;
rc = SUPR3CallVMMR0Ex(pDrvIns->Internal.s.pVMR3->pVMR0, NIL_VMCPUID, uOperation, 0, (PSUPVMMR0REQHDR)pvArg);
LogFlow(("pdmR3DrvHlp_SUPCallVMMR0Ex: caller='%s'/%d: returns %Rrc\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, rc));
return rc;
static DECLCALLBACK(int) pdmR3DrvHlp_USBRegisterHub(PPDMDRVINS pDrvIns, uint32_t fVersions, uint32_t cPorts, PCPDMUSBHUBREG pUsbHubReg, PPCPDMUSBHUBHLP ppUsbHubHlp)
LogFlow(("pdmR3DrvHlp_USBRegisterHub: caller='%s'/%d: fVersions=%#x cPorts=%#x pUsbHubReg=%p ppUsbHubHlp=%p\n",
#ifdef VBOX_WITH_USB
int rc = pdmR3UsbRegisterHub(pDrvIns->Internal.s.pVMR3, pDrvIns, fVersions, cPorts, pUsbHubReg, ppUsbHubHlp);
LogFlow(("pdmR3DrvHlp_USBRegisterHub: caller='%s'/%d: returns %Rrc\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, rc));
return rc;
static DECLCALLBACK(int) pdmR3DrvHlp_SetAsyncNotification(PPDMDRVINS pDrvIns, PFNPDMDRVASYNCNOTIFY pfnAsyncNotify)
LogFlow(("pdmR3DrvHlp_SetAsyncNotification: caller='%s'/%d: pfnAsyncNotify=%p\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, pfnAsyncNotify));
AssertStmt(pDrvIns->Internal.s.fVMSuspended || pDrvIns->Internal.s.fVMReset, rc = VERR_WRONG_ORDER);
LogFlow(("pdmR3DrvHlp_SetAsyncNotification: caller='%s'/%d: returns %Rrc\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, rc));
return rc;
LogFlow(("pdmR3DrvHlp_AsyncNotificationCompleted: caller='%s'/%d:\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance));
LogFlow(("pdmR3DrvHlp_AsyncNotificationCompleted: caller='%s'/%d: enmVMState=%d\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, enmVMState));
static DECLCALLBACK(int) pdmR3DrvHlp_PDMThreadCreate(PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
LogFlow(("pdmR3DrvHlp_PDMThreadCreate: caller='%s'/%d: ppThread=%p pvUser=%p pfnThread=%p pfnWakeup=%p cbStack=%#zx enmType=%d pszName=%p:{%s}\n",
pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName, pszName));
int rc = pdmR3ThreadCreateDriver(pDrvIns->Internal.s.pVMR3, pDrvIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
LogFlow(("pdmR3DrvHlp_PDMThreadCreate: caller='%s'/%d: returns %Rrc *ppThread=%RTthrd\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance,
return rc;
static DECLCALLBACK(int) pdmR3DrvHlp_PDMAsyncCompletionTemplateCreate(PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate,
const char *pszDesc)
LogFlow(("pdmR3DrvHlp_PDMAsyncCompletionTemplateCreate: caller='%s'/%d: ppTemplate=%p pfnCompleted=%p pszDesc=%p:{%s}\n",
int rc = PDMR3AsyncCompletionTemplateCreateDriver(pDrvIns->Internal.s.pVMR3, pDrvIns, ppTemplate, pfnCompleted, pvTemplateUser, pszDesc);
LogFlow(("pdmR3DrvHlp_PDMAsyncCompletionTemplateCreate: caller='%s'/%d: returns %Rrc *ppThread=%p\n", pDrvIns->pDrvReg->szDriverName,
return rc;