275
275
* Validate the registration structure.
278
if (pDrvReg->u32Version != PDM_DRVREG_VERSION)
280
AssertMsgFailed(("Unknown struct version %#x!\n", pDrvReg->u32Version));
281
return VERR_PDM_UNKNOWN_DRVREG_VERSION;
283
if ( !pDrvReg->szDriverName[0]
284
|| strlen(pDrvReg->szDriverName) >= sizeof(pDrvReg->szDriverName))
286
AssertMsgFailed(("Invalid name '%s'\n", pDrvReg->szDriverName));
287
return VERR_PDM_INVALID_DRIVER_REGISTRATION;
289
if ((pDrvReg->fFlags & PDM_DRVREG_FLAGS_HOST_BITS_MASK) != PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT)
291
AssertMsgFailed(("Invalid host bits flags! fFlags=%#x (Driver %s)\n", pDrvReg->fFlags, pDrvReg->szDriverName));
292
return VERR_PDM_INVALID_DRIVER_HOST_BITS;
294
if (pDrvReg->cMaxInstances <= 0)
296
AssertMsgFailed(("Max instances %u! (Driver %s)\n", pDrvReg->cMaxInstances, pDrvReg->szDriverName));
297
return VERR_PDM_INVALID_DRIVER_REGISTRATION;
299
if (pDrvReg->cbInstance > _1M)
301
AssertMsgFailed(("Instance size above 1MB, %d bytes! (Driver %s)\n", pDrvReg->cbInstance, pDrvReg->szDriverName));
302
return VERR_PDM_INVALID_DRIVER_REGISTRATION;
304
if (!pDrvReg->pfnConstruct)
306
AssertMsgFailed(("No constructore! (Driver %s)\n", pDrvReg->szDriverName));
307
return VERR_PDM_INVALID_DRIVER_REGISTRATION;
277
AssertPtrReturn(pDrvReg, VERR_INVALID_POINTER);
278
AssertMsgReturn(pDrvReg->u32Version == PDM_DRVREG_VERSION, ("%#x\n", pDrvReg->u32Version), VERR_PDM_UNKNOWN_DRVREG_VERSION);
279
AssertReturn(pDrvReg->szDriverName[0], VERR_PDM_INVALID_DRIVER_REGISTRATION);
280
AssertMsgReturn(memchr(pDrvReg->szDriverName, '\0', sizeof(pDrvReg->szDriverName)),
281
(".*s\n", sizeof(pDrvReg->szDriverName), pDrvReg->szDriverName),
282
VERR_PDM_INVALID_DRIVER_REGISTRATION);
283
AssertMsgReturn((pDrvReg->fFlags & PDM_DRVREG_FLAGS_HOST_BITS_MASK) == PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
284
("%s: fFlags=%#x\n", pDrvReg->szDriverName, pDrvReg->fFlags),
285
VERR_PDM_INVALID_DRIVER_HOST_BITS);
286
AssertMsgReturn(pDrvReg->cMaxInstances > 0, ("%s: %#x\n", pDrvReg->szDriverName, pDrvReg->cMaxInstances),
287
VERR_PDM_INVALID_DRIVER_REGISTRATION);
288
AssertMsgReturn(pDrvReg->cbInstance <= _1M, ("%s: %#x\n", pDrvReg->szDriverName, pDrvReg->cbInstance),
289
VERR_PDM_INVALID_DRIVER_REGISTRATION);
290
AssertMsgReturn(VALID_PTR(pDrvReg->pfnConstruct), ("%s: %p\n", pDrvReg->szDriverName, pDrvReg->pfnConstruct),
291
VERR_PDM_INVALID_DRIVER_REGISTRATION);
292
AssertMsgReturn(pDrvReg->pfnSoftReset == NULL, ("%s: %p\n", pDrvReg->szDriverName, pDrvReg->pfnSoftReset),
293
VERR_PDM_INVALID_DRIVER_REGISTRATION);
294
AssertMsgReturn(pDrvReg->u32VersionEnd == PDM_DRVREG_VERSION, ("%s: #x\n", pDrvReg->szDriverName, pDrvReg->u32VersionEnd),
295
VERR_PDM_INVALID_DRIVER_REGISTRATION);
311
298
* Check for duplicate and find FIFO entry at the same time.
491
480
/** @copydoc PDMDRVHLP::pfnAttach */
492
static DECLCALLBACK(int) pdmR3DrvHlp_Attach(PPDMDRVINS pDrvIns, PPDMIBASE *ppBaseInterface)
481
static DECLCALLBACK(int) pdmR3DrvHlp_Attach(PPDMDRVINS pDrvIns, uint32_t fFlags, PPDMIBASE *ppBaseInterface)
494
483
PDMDRV_ASSERT_DRVINS(pDrvIns);
495
484
VM_ASSERT_EMT(pDrvIns->Internal.s.pVM);
496
485
LogFlow(("pdmR3DrvHlp_Attach: caller='%s'/%d:\n",
497
486
pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance));
487
Assert(!(fFlags & ~(PDM_TACH_FLAGS_NOT_HOT_PLUG)));
500
490
* Check that there isn't anything attached already.
621
619
/** @copydoc PDMDRVHLP::pfnDetach */
622
static DECLCALLBACK(int) pdmR3DrvHlp_Detach(PPDMDRVINS pDrvIns)
620
static DECLCALLBACK(int) pdmR3DrvHlp_Detach(PPDMDRVINS pDrvIns, uint32_t fFlags)
624
622
PDMDRV_ASSERT_DRVINS(pDrvIns);
625
LogFlow(("pdmR3DrvHlp_Detach: caller='%s'/%d:\n",
626
pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance));
623
LogFlow(("pdmR3DrvHlp_Detach: caller='%s'/%d: fFlags=%#x\n",
624
pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, fFlags));
627
625
VM_ASSERT_EMT(pDrvIns->Internal.s.pVM);
649
645
/** @copydoc PDMDRVHLP::pfnDetachSelf */
650
static DECLCALLBACK(int) pdmR3DrvHlp_DetachSelf(PPDMDRVINS pDrvIns)
646
static DECLCALLBACK(int) pdmR3DrvHlp_DetachSelf(PPDMDRVINS pDrvIns, uint32_t fFlags)
652
648
PDMDRV_ASSERT_DRVINS(pDrvIns);
653
LogFlow(("pdmR3DrvHlp_DetachSelf: caller='%s'/%d:\n",
654
pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance));
649
LogFlow(("pdmR3DrvHlp_DetachSelf: caller='%s'/%d: fFlags=%#x\n",
650
pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, fFlags));
655
651
VM_ASSERT_EMT(pDrvIns->Internal.s.pVM);
657
int rc = pdmR3DrvDetach(pDrvIns);
653
int rc = pdmR3DrvDetach(pDrvIns, fFlags);
659
655
LogFlow(("pdmR3DrvHlp_Detach: returns %Rrc\n", rc)); /* pDrvIns is freed by now. */
808
/** @copydoc PDMDEVHLPR3::pfnVMState */
809
static DECLCALLBACK(VMSTATE) pdmR3DrvHlp_VMState(PPDMDRVINS pDrvIns)
811
PDMDRV_ASSERT_DRVINS(pDrvIns);
813
VMSTATE enmVMState = VMR3GetState(pDrvIns->Internal.s.pVM);
815
LogFlow(("pdmR3DrvHlp_VMState: caller='%s'/%d: returns %d (%s)\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance,
816
enmVMState, VMR3GetStateName(enmVMState)));
821
/** @copydoc PDMDEVHLPR3::pfnVMTeleportedAndNotFullyResumedYet */
822
static DECLCALLBACK(bool) pdmR3DrvHlp_VMTeleportedAndNotFullyResumedYet(PPDMDRVINS pDrvIns)
824
PDMDRV_ASSERT_DRVINS(pDrvIns);
826
bool fRc = VMR3TeleportedAndNotFullyResumedYet(pDrvIns->Internal.s.pVM);
828
LogFlow(("pdmR3DrvHlp_VMState: caller='%s'/%d: returns %RTbool)\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance,
812
834
/** @copydoc PDMDRVHLP::pfnPDMQueueCreate */
813
static DECLCALLBACK(int) pdmR3DrvHlp_PDMQueueCreate(PPDMDRVINS pDrvIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval, PFNPDMQUEUEDRV pfnCallback, PPDMQUEUE *ppQueue)
835
static DECLCALLBACK(int) pdmR3DrvHlp_PDMQueueCreate(PPDMDRVINS pDrvIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval,
836
PFNPDMQUEUEDRV pfnCallback, const char *pszName, PPDMQUEUE *ppQueue)
815
838
PDMDRV_ASSERT_DRVINS(pDrvIns);
816
LogFlow(("pdmR3DrvHlp_PDMQueueCreate: caller='%s'/%d: cbItem=%d cItems=%d cMilliesInterval=%d pfnCallback=%p ppQueue=%p\n",
817
pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, cbItem, cItems, cMilliesInterval, pfnCallback, ppQueue, ppQueue));
818
VM_ASSERT_EMT(pDrvIns->Internal.s.pVM);
820
int rc = PDMR3QueueCreateDriver(pDrvIns->Internal.s.pVM, pDrvIns, cbItem, cItems, cMilliesInterval, pfnCallback, ppQueue);
839
LogFlow(("pdmR3DrvHlp_PDMQueueCreate: caller='%s'/%d: cbItem=%d cItems=%d cMilliesInterval=%d pfnCallback=%p pszName=%p:{%s} ppQueue=%p\n",
840
pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, cbItem, cItems, cMilliesInterval, pfnCallback, pszName, pszName, ppQueue, ppQueue));
841
PVM pVM = pDrvIns->Internal.s.pVM;
844
if (pDrvIns->iInstance > 0)
846
pszName = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DRIVER_DESC, "%s_%u", pszName, pDrvIns->iInstance);
847
AssertLogRelReturn(pszName, VERR_NO_MEMORY);
850
int rc = PDMR3QueueCreateDriver(pVM, pDrvIns, cbItem, cItems, cMilliesInterval, pfnCallback, pszName, ppQueue);
822
852
LogFlow(("pdmR3DrvHlp_PDMQueueCreate: caller='%s'/%d: returns %Rrc *ppQueue=%p\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, rc, *ppQueue));
827
/** @copydoc PDMDRVHLP::pfnPDMPollerRegister */
828
static DECLCALLBACK(int) pdmR3DrvHlp_PDMPollerRegister(PPDMDRVINS pDrvIns, PFNPDMDRVPOLLER pfnPoller)
830
PDMDRV_ASSERT_DRVINS(pDrvIns);
831
AssertLogRelMsgFailedReturn(("pdmR3DrvHlp_PDMPollerRegister: caller='%s'/%d: pfnPoller=%p -> VERR_NOT_SUPPORTED\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, pfnPoller),
836
857
/** @copydoc PDMDRVHLP::pfnTMGetVirtualFreq */
837
858
static DECLCALLBACK(uint64_t) pdmR3DrvHlp_TMGetVirtualFreq(PPDMDRVINS pDrvIns)
869
890
/** @copydoc PDMDRVHLP::pfnSSMRegister */
870
static DECLCALLBACK(int) pdmR3DrvHlp_SSMRegister(PPDMDRVINS pDrvIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess,
891
static DECLCALLBACK(int) pdmR3DrvHlp_SSMRegister(PPDMDRVINS pDrvIns, uint32_t uVersion, size_t cbGuess,
892
PFNSSMDRVLIVEPREP pfnLivePrep, PFNSSMDRVLIVEEXEC pfnLiveExec, PFNSSMDRVLIVEVOTE pfnLiveVote,
871
893
PFNSSMDRVSAVEPREP pfnSavePrep, PFNSSMDRVSAVEEXEC pfnSaveExec, PFNSSMDRVSAVEDONE pfnSaveDone,
872
894
PFNSSMDRVLOADPREP pfnLoadPrep, PFNSSMDRVLOADEXEC pfnLoadExec, PFNSSMDRVLOADDONE pfnLoadDone)
874
896
PDMDRV_ASSERT_DRVINS(pDrvIns);
875
897
VM_ASSERT_EMT(pDrvIns->Internal.s.pVM);
876
LogFlow(("pdmR3DrvHlp_SSMRegister: caller='%s'/%d: pszName=%p:{%s} u32Instance=%#x u32Version=#x cbGuess=%#x pfnSavePrep=%p pfnSaveExec=%p pfnSaveDone=%p pszLoadPrep=%p pfnLoadExec=%p pfnLoaddone=%p\n",
877
pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, pszName, pszName, u32Instance, u32Version, cbGuess, pfnSavePrep, pfnSaveExec, pfnSaveDone, pfnLoadPrep, pfnLoadExec, pfnLoadDone));
898
LogFlow(("pdmR3DrvHlp_SSMRegister: caller='%s'/%d: uVersion=#x cbGuess=%#x \n"
899
" pfnLivePrep=%p pfnLiveExec=%p pfnLiveVote=%p pfnSavePrep=%p pfnSaveExec=%p pfnSaveDone=%p pszLoadPrep=%p pfnLoadExec=%p pfnLoaddone=%p\n",
900
pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, uVersion, cbGuess,
901
pfnLivePrep, pfnLiveExec, pfnLiveVote,
902
pfnSavePrep, pfnSaveExec, pfnSaveDone, pfnLoadPrep, pfnLoadExec, pfnLoadDone));
879
int rc = SSMR3RegisterDriver(pDrvIns->Internal.s.pVM, pDrvIns, pszName, u32Instance, u32Version, cbGuess,
904
int rc = SSMR3RegisterDriver(pDrvIns->Internal.s.pVM, pDrvIns, pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance,
906
pfnLivePrep, pfnLiveExec, pfnLiveVote,
880
907
pfnSavePrep, pfnSaveExec, pfnSaveDone,
881
908
pfnLoadPrep, pfnLoadExec, pfnLoadDone);
1021
/** @copydoc PDMDRVHLP::pfnSetAsyncNotification */
1022
static DECLCALLBACK(int) pdmR3DrvHlp_SetAsyncNotification(PPDMDRVINS pDrvIns, PFNPDMDRVASYNCNOTIFY pfnAsyncNotify)
1024
PDMDRV_ASSERT_DRVINS(pDrvIns);
1025
VM_ASSERT_EMT0(pDrvIns->Internal.s.pVM);
1026
LogFlow(("pdmR3DrvHlp_SetAsyncNotification: caller='%s'/%d: pfnAsyncNotify=%p\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, pfnAsyncNotify));
1028
int rc = VINF_SUCCESS;
1029
AssertStmt(pfnAsyncNotify, rc = VERR_INVALID_PARAMETER);
1030
AssertStmt(!pDrvIns->Internal.s.pfnAsyncNotify, rc = VERR_WRONG_ORDER);
1031
AssertStmt(pDrvIns->Internal.s.fVMSuspended || pDrvIns->Internal.s.fVMReset, rc = VERR_WRONG_ORDER);
1032
VMSTATE enmVMState = VMR3GetState(pDrvIns->Internal.s.pVM);
1033
AssertStmt( enmVMState == VMSTATE_SUSPENDING
1034
|| enmVMState == VMSTATE_SUSPENDING_EXT_LS
1035
|| enmVMState == VMSTATE_SUSPENDING_LS
1036
|| enmVMState == VMSTATE_RESETTING
1037
|| enmVMState == VMSTATE_RESETTING_LS
1038
|| enmVMState == VMSTATE_POWERING_OFF
1039
|| enmVMState == VMSTATE_POWERING_OFF_LS,
1040
rc = VERR_INVALID_STATE);
1043
pDrvIns->Internal.s.pfnAsyncNotify = pfnAsyncNotify;
1045
LogFlow(("pdmR3DrvHlp_SetAsyncNotification: caller='%s'/%d: returns %Rrc\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, rc));
1050
/** @copydoc PDMDRVHLP::pfnAsyncNotificationCompleted */
1051
static DECLCALLBACK(void) pdmR3DrvHlp_AsyncNotificationCompleted(PPDMDRVINS pDrvIns)
1053
PDMDRV_ASSERT_DRVINS(pDrvIns);
1054
PVM pVM = pDrvIns->Internal.s.pVM;
1056
VMSTATE enmVMState = VMR3GetState(pVM);
1057
if ( enmVMState == VMSTATE_SUSPENDING
1058
|| enmVMState == VMSTATE_SUSPENDING_EXT_LS
1059
|| enmVMState == VMSTATE_SUSPENDING_LS
1060
|| enmVMState == VMSTATE_RESETTING
1061
|| enmVMState == VMSTATE_RESETTING_LS
1062
|| enmVMState == VMSTATE_POWERING_OFF
1063
|| enmVMState == VMSTATE_POWERING_OFF_LS)
1065
LogFlow(("pdmR3DrvHlp_AsyncNotificationCompleted: caller='%s'/%d:\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance));
1066
VMR3AsyncPdmNotificationWakeupU(pVM->pUVM);
1069
LogFlow(("pdmR3DrvHlp_AsyncNotificationCompleted: caller='%s'/%d: enmVMState=%d\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, enmVMState));
994
1073
/** @copydoc PDMDRVHLP::pfnPDMThreadCreate */
995
1074
static DECLCALLBACK(int) pdmR3DrvHlp_PDMThreadCreate(PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
996
1075
PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
1011
/** @copydoc PDMDEVHLPR3::pfnVMState */
1012
static DECLCALLBACK(VMSTATE) pdmR3DrvHlp_VMState(PPDMDRVINS pDrvIns)
1014
PDMDRV_ASSERT_DRVINS(pDrvIns);
1016
VMSTATE enmVMState = VMR3GetState(pDrvIns->Internal.s.pVM);
1018
LogFlow(("pdmR3DrvHlp_VMState: caller='%s'/%d: returns %d (%s)\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance,
1019
enmVMState, VMR3GetStateName(enmVMState)));
1024
1090
#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
1025
1091
/** @copydoc PDMDRVHLP::pfnPDMAsyncCompletionTemplateCreate */
1026
1092
static DECLCALLBACK(int) pdmR3DrvHlp_PDMAsyncCompletionTemplateCreate(PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate,
1057
1123
pdmR3DrvHlp_VMSetErrorV,
1058
1124
pdmR3DrvHlp_VMSetRuntimeError,
1059
1125
pdmR3DrvHlp_VMSetRuntimeErrorV,
1126
pdmR3DrvHlp_VMState,
1127
pdmR3DrvHlp_VMTeleportedAndNotFullyResumedYet,
1060
1128
pdmR3DrvHlp_PDMQueueCreate,
1061
pdmR3DrvHlp_PDMPollerRegister,
1062
1129
pdmR3DrvHlp_TMGetVirtualFreq,
1063
1130
pdmR3DrvHlp_TMGetVirtualTime,
1064
1131
pdmR3DrvHlp_TMTimerCreate,
1070
1137
pdmR3DrvHlp_STAMDeregister,
1071
1138
pdmR3DrvHlp_SUPCallVMMR0Ex,
1072
1139
pdmR3DrvHlp_USBRegisterHub,
1140
pdmR3DrvHlp_SetAsyncNotification,
1141
pdmR3DrvHlp_AsyncNotificationCompleted,
1073
1142
pdmR3DrvHlp_PDMThreadCreate,
1074
pdmR3DrvHlp_VMState,
1075
1143
#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
1076
1144
pdmR3DrvHlp_PDMAsyncCompletionTemplateCreate,