~ubuntu-branches/ubuntu/trusty/virtualbox-ose/trusty

« back to all changes in this revision

Viewing changes to src/VBox/VMM/PDMDriver.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2009-12-18 16:44:29 UTC
  • mfrom: (0.3.3 upstream) (0.4.6 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091218164429-jd34ccexpv5na11a
Tags: 3.1.2-dfsg-1ubuntu1
* Merge from Debian unstable (LP: #498219), remaining changes:
  - Disable update action
    - debian/patches/u01-disable-update-action.dpatch
  - VirtualBox should go in Accessories, not in System tools (LP: #288590)
    - debian/virtualbox-ose-qt.files/virtualbox-ose.desktop
  - Add Apport hook
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Add Launchpad integration
    - debian/control
    - debian/lpi-bug.xpm
    - debian/patches/u02-lp-integration.dpatch
* Fixes the following bugs:
  - Kernel module fails to build with Linux >= 2.6.32 (LP: #474625)
  - X.Org drivers need to be rebuilt against X-Server 1.7 (LP: #495935)
  - The *-source packages try to build the kernel modules even though the
    kernel headers aren't available (LP: #473334)
* Replace *-source packages with transitional packages for *-dkms.
* Adapt u01-disable-update-action.dpatch and u02-lp-integration.dpatch for
  new upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
274
274
    /*
275
275
     * Validate the registration structure.
276
276
     */
277
 
    Assert(pDrvReg);
278
 
    if (pDrvReg->u32Version != PDM_DRVREG_VERSION)
279
 
    {
280
 
        AssertMsgFailed(("Unknown struct version %#x!\n", pDrvReg->u32Version));
281
 
        return VERR_PDM_UNKNOWN_DRVREG_VERSION;
282
 
    }
283
 
    if (    !pDrvReg->szDriverName[0]
284
 
        ||  strlen(pDrvReg->szDriverName) >= sizeof(pDrvReg->szDriverName))
285
 
    {
286
 
        AssertMsgFailed(("Invalid name '%s'\n", pDrvReg->szDriverName));
287
 
        return VERR_PDM_INVALID_DRIVER_REGISTRATION;
288
 
    }
289
 
    if ((pDrvReg->fFlags & PDM_DRVREG_FLAGS_HOST_BITS_MASK) != PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT)
290
 
    {
291
 
        AssertMsgFailed(("Invalid host bits flags! fFlags=%#x (Driver %s)\n", pDrvReg->fFlags, pDrvReg->szDriverName));
292
 
        return VERR_PDM_INVALID_DRIVER_HOST_BITS;
293
 
    }
294
 
    if (pDrvReg->cMaxInstances <= 0)
295
 
    {
296
 
        AssertMsgFailed(("Max instances %u! (Driver %s)\n", pDrvReg->cMaxInstances, pDrvReg->szDriverName));
297
 
        return VERR_PDM_INVALID_DRIVER_REGISTRATION;
298
 
    }
299
 
    if (pDrvReg->cbInstance > _1M)
300
 
    {
301
 
        AssertMsgFailed(("Instance size above 1MB, %d bytes! (Driver %s)\n", pDrvReg->cbInstance, pDrvReg->szDriverName));
302
 
        return VERR_PDM_INVALID_DRIVER_REGISTRATION;
303
 
    }
304
 
    if (!pDrvReg->pfnConstruct)
305
 
    {
306
 
        AssertMsgFailed(("No constructore! (Driver %s)\n", pDrvReg->szDriverName));
307
 
        return VERR_PDM_INVALID_DRIVER_REGISTRATION;
308
 
    }
 
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);
309
296
 
310
297
    /*
311
298
     * Check for duplicate and find FIFO entry at the same time.
362
349
 *
363
350
 * @returns VINF_SUCCESS
364
351
 * @param   pDrvIns     The driver instance to detach.
 
352
 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
365
353
 */
366
 
int pdmR3DrvDetach(PPDMDRVINS pDrvIns)
 
354
int pdmR3DrvDetach(PPDMDRVINS pDrvIns, uint32_t fFlags)
367
355
{
368
356
    PDMDRV_ASSERT_DRVINS(pDrvIns);
369
357
    LogFlow(("pdmR3DrvDetach: pDrvIns=%p '%s'/%d\n", pDrvIns, pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance));
383
371
     * The requirement is that the driver/device above has a detach method.
384
372
     */
385
373
    if (pDrvIns->Internal.s.pUp
386
 
            ? !pDrvIns->Internal.s.pUp->pDrvReg->pfnDetach
387
 
            : !pDrvIns->Internal.s.pLun->pDevIns->pDevReg->pfnDetach)
 
374
        ? !pDrvIns->Internal.s.pUp->pDrvReg->pfnDetach
 
375
        : !pDrvIns->Internal.s.pLun->pDevIns->pDevReg->pfnDetach)
388
376
    {
389
377
        AssertMsgFailed(("Cannot detach driver instance because the driver/device above doesn't support it!\n"));
390
378
        return VERR_PDM_DRIVER_DETACH_NOT_POSSIBLE;
393
381
    /*
394
382
     * Join paths with pdmR3DrvDestroyChain.
395
383
     */
396
 
    pdmR3DrvDestroyChain(pDrvIns);
 
384
    pdmR3DrvDestroyChain(pDrvIns, fFlags);
397
385
    return VINF_SUCCESS;
398
386
}
399
387
 
404
392
 * This is used when unplugging a device at run time.
405
393
 *
406
394
 * @param   pDrvIns     Pointer to the driver instance to start with.
 
395
 * @param   fFlags      PDM_TACH_FLAGS_NOT_HOT_PLUG or 0.
407
396
 */
408
 
void pdmR3DrvDestroyChain(PPDMDRVINS pDrvIns)
 
397
void pdmR3DrvDestroyChain(PPDMDRVINS pDrvIns, uint32_t fFlags)
409
398
{
410
399
    VM_ASSERT_EMT(pDrvIns->Internal.s.pVM);
411
400
 
439
428
            pParent->Internal.s.pDown = NULL;
440
429
 
441
430
            if (pParent->pDrvReg->pfnDetach)
442
 
                pParent->pDrvReg->pfnDetach(pParent);
 
431
                pParent->pDrvReg->pfnDetach(pParent, fFlags);
443
432
 
444
433
            pParent->pDownBase = NULL;
445
434
        }
449
438
            Assert(pLun->pTop == pCur);
450
439
            pLun->pTop = NULL;
451
440
            if (pLun->pDevIns->pDevReg->pfnDetach)
452
 
                pLun->pDevIns->pDevReg->pfnDetach(pLun->pDevIns, pLun->iLun);
 
441
                pLun->pDevIns->pDevReg->pfnDetach(pLun->pDevIns, pLun->iLun, fFlags);
453
442
        }
454
443
 
455
444
        /*
489
478
 */
490
479
 
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)
493
482
{
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)));
498
488
 
499
489
    /*
500
490
     * Check that there isn't anything attached already.
519
509
                 */
520
510
                PVM pVM = pDrvIns->Internal.s.pVM;
521
511
                PPDMDRV pDrv = pdmR3DrvLookup(pVM, pszName);
522
 
                if (pDrv)
 
512
                if (    pDrv
 
513
                    &&  pDrv->cInstances < pDrv->pDrvReg->cMaxInstances)
523
514
                {
524
515
                    /* config node */
525
516
                    PCFGMNODE pConfigNode = CFGMR3GetChild(pNode, "Config");
544
535
                            pNew->Internal.s.pDrv           = pDrv;
545
536
                            pNew->Internal.s.pVM            = pVM;
546
537
                            pNew->Internal.s.fDetaching     = false;
 
538
                            pNew->Internal.s.fVMSuspended   = true;
 
539
                            pNew->Internal.s.pfnAsyncNotify = NULL;
547
540
                            pNew->Internal.s.pCfgHandle     = pNode;
548
541
                            pNew->pDrvHlp                   = &g_pdmR3DrvHlp;
549
542
                            pNew->pDrvReg                   = pDrv->pDrvReg;
561
554
                            pDrvIns->Internal.s.pLun->pBottom = pNew;
562
555
 
563
556
                            Log(("PDM: Constructing driver '%s' instance %d...\n", pNew->pDrvReg->szDriverName, pNew->iInstance));
564
 
                            rc = pDrv->pDrvReg->pfnConstruct(pNew, pNew->pCfgHandle);
 
557
                            rc = pDrv->pDrvReg->pfnConstruct(pNew, pNew->pCfgHandle, 0 /*fFlags*/);
565
558
                            if (RT_SUCCESS(rc))
566
559
                            {
567
560
                                *ppBaseInterface = &pNew->IBase;
589
582
                    else
590
583
                        AssertMsgFailed(("Failed to create Config node! rc=%Rrc\n", rc));
591
584
                }
 
585
                else if (pDrv)
 
586
                {
 
587
                    AssertMsgFailed(("Too many instances of driver '%s', max is %u\n", pszName, pDrv->pDrvReg->cMaxInstances));
 
588
                    rc = VERR_PDM_TOO_MANY_DRIVER_INSTANCES;
 
589
                }
592
590
                else
593
591
                {
594
592
                    AssertMsgFailed(("Driver '%s' wasn't found!\n", pszName));
619
617
 
620
618
 
621
619
/** @copydoc PDMDRVHLP::pfnDetach */
622
 
static DECLCALLBACK(int) pdmR3DrvHlp_Detach(PPDMDRVINS pDrvIns)
 
620
static DECLCALLBACK(int) pdmR3DrvHlp_Detach(PPDMDRVINS pDrvIns, uint32_t fFlags)
623
621
{
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);
628
626
 
629
627
    /*
631
629
     */
632
630
    int rc;
633
631
    if (pDrvIns->Internal.s.pDown)
634
 
    {
635
 
        rc = pdmR3DrvDetach(pDrvIns->Internal.s.pDown);
636
 
    }
 
632
        rc = pdmR3DrvDetach(pDrvIns->Internal.s.pDown, fFlags);
637
633
    else
638
634
    {
639
635
        AssertMsgFailed(("Nothing attached!\n"));
647
643
 
648
644
 
649
645
/** @copydoc PDMDRVHLP::pfnDetachSelf */
650
 
static DECLCALLBACK(int) pdmR3DrvHlp_DetachSelf(PPDMDRVINS pDrvIns)
 
646
static DECLCALLBACK(int) pdmR3DrvHlp_DetachSelf(PPDMDRVINS pDrvIns, uint32_t fFlags)
651
647
{
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);
656
652
 
657
 
    int rc = pdmR3DrvDetach(pDrvIns);
 
653
    int rc = pdmR3DrvDetach(pDrvIns, fFlags);
658
654
 
659
655
    LogFlow(("pdmR3DrvHlp_Detach: returns %Rrc\n", rc)); /* pDrvIns is freed by now. */
660
656
    return rc;
809
805
}
810
806
 
811
807
 
 
808
/** @copydoc PDMDEVHLPR3::pfnVMState */
 
809
static DECLCALLBACK(VMSTATE) pdmR3DrvHlp_VMState(PPDMDRVINS pDrvIns)
 
810
{
 
811
    PDMDRV_ASSERT_DRVINS(pDrvIns);
 
812
 
 
813
    VMSTATE enmVMState = VMR3GetState(pDrvIns->Internal.s.pVM);
 
814
 
 
815
    LogFlow(("pdmR3DrvHlp_VMState: caller='%s'/%d: returns %d (%s)\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance,
 
816
             enmVMState, VMR3GetStateName(enmVMState)));
 
817
    return enmVMState;
 
818
}
 
819
 
 
820
 
 
821
/** @copydoc PDMDEVHLPR3::pfnVMTeleportedAndNotFullyResumedYet */
 
822
static DECLCALLBACK(bool) pdmR3DrvHlp_VMTeleportedAndNotFullyResumedYet(PPDMDRVINS pDrvIns)
 
823
{
 
824
    PDMDRV_ASSERT_DRVINS(pDrvIns);
 
825
 
 
826
    bool fRc = VMR3TeleportedAndNotFullyResumedYet(pDrvIns->Internal.s.pVM);
 
827
 
 
828
    LogFlow(("pdmR3DrvHlp_VMState: caller='%s'/%d: returns %RTbool)\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance,
 
829
             fRc));
 
830
    return fRc;
 
831
}
 
832
 
 
833
 
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)
814
837
{
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);
819
 
 
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;
 
842
    VM_ASSERT_EMT(pVM);
 
843
 
 
844
    if (pDrvIns->iInstance > 0)
 
845
    {
 
846
        pszName = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DRIVER_DESC, "%s_%u", pszName, pDrvIns->iInstance);
 
847
        AssertLogRelReturn(pszName, VERR_NO_MEMORY);
 
848
    }
 
849
 
 
850
    int rc = PDMR3QueueCreateDriver(pVM, pDrvIns, cbItem, cItems, cMilliesInterval, pfnCallback, pszName, ppQueue);
821
851
 
822
852
    LogFlow(("pdmR3DrvHlp_PDMQueueCreate: caller='%s'/%d: returns %Rrc *ppQueue=%p\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, rc, *ppQueue));
823
853
    return rc;
824
854
}
825
855
 
826
856
 
827
 
/** @copydoc PDMDRVHLP::pfnPDMPollerRegister */
828
 
static DECLCALLBACK(int) pdmR3DrvHlp_PDMPollerRegister(PPDMDRVINS pDrvIns, PFNPDMDRVPOLLER pfnPoller)
829
 
{
830
 
    PDMDRV_ASSERT_DRVINS(pDrvIns);
831
 
    AssertLogRelMsgFailedReturn(("pdmR3DrvHlp_PDMPollerRegister: caller='%s'/%d: pfnPoller=%p -> VERR_NOT_SUPPORTED\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, pfnPoller),
832
 
                                VERR_NOT_SUPPORTED);
833
 
}
834
 
 
835
 
 
836
857
/** @copydoc PDMDRVHLP::pfnTMGetVirtualFreq */
837
858
static DECLCALLBACK(uint64_t) pdmR3DrvHlp_TMGetVirtualFreq(PPDMDRVINS pDrvIns)
838
859
{
867
888
 
868
889
 
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)
873
895
{
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));
878
903
 
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,
 
905
                                 uVersion, cbGuess,
 
906
                                 pfnLivePrep, pfnLiveExec, pfnLiveVote,
880
907
                                 pfnSavePrep, pfnSaveExec, pfnSaveDone,
881
908
                                 pfnLoadPrep, pfnLoadExec, pfnLoadDone);
882
909
 
991
1018
}
992
1019
 
993
1020
 
 
1021
/** @copydoc PDMDRVHLP::pfnSetAsyncNotification */
 
1022
static DECLCALLBACK(int) pdmR3DrvHlp_SetAsyncNotification(PPDMDRVINS pDrvIns, PFNPDMDRVASYNCNOTIFY pfnAsyncNotify)
 
1023
{
 
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));
 
1027
 
 
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);
 
1041
 
 
1042
    if (RT_SUCCESS(rc))
 
1043
        pDrvIns->Internal.s.pfnAsyncNotify = pfnAsyncNotify;
 
1044
 
 
1045
    LogFlow(("pdmR3DrvHlp_SetAsyncNotification: caller='%s'/%d: returns %Rrc\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, rc));
 
1046
    return rc;
 
1047
}
 
1048
 
 
1049
 
 
1050
/** @copydoc PDMDRVHLP::pfnAsyncNotificationCompleted */
 
1051
static DECLCALLBACK(void) pdmR3DrvHlp_AsyncNotificationCompleted(PPDMDRVINS pDrvIns)
 
1052
{
 
1053
    PDMDRV_ASSERT_DRVINS(pDrvIns);
 
1054
    PVM pVM = pDrvIns->Internal.s.pVM;
 
1055
 
 
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)
 
1064
    {
 
1065
        LogFlow(("pdmR3DrvHlp_AsyncNotificationCompleted: caller='%s'/%d:\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance));
 
1066
        VMR3AsyncPdmNotificationWakeupU(pVM->pUVM);
 
1067
    }
 
1068
    else
 
1069
        LogFlow(("pdmR3DrvHlp_AsyncNotificationCompleted: caller='%s'/%d: enmVMState=%d\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, enmVMState));
 
1070
}
 
1071
 
 
1072
 
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)
1008
1087
}
1009
1088
 
1010
1089
 
1011
 
/** @copydoc PDMDEVHLPR3::pfnVMState */
1012
 
static DECLCALLBACK(VMSTATE) pdmR3DrvHlp_VMState(PPDMDRVINS pDrvIns)
1013
 
{
1014
 
    PDMDRV_ASSERT_DRVINS(pDrvIns);
1015
 
 
1016
 
    VMSTATE enmVMState = VMR3GetState(pDrvIns->Internal.s.pVM);
1017
 
 
1018
 
    LogFlow(("pdmR3DrvHlp_VMState: caller='%s'/%d: returns %d (%s)\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance,
1019
 
             enmVMState, VMR3GetStateName(enmVMState)));
1020
 
    return enmVMState;
1021
 
}
1022
 
 
1023
 
 
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,
1077
1145
#endif