VirtualBox

Changeset 81675 in vbox


Ignore:
Timestamp:
Nov 5, 2019 4:13:34 PM (5 years ago)
Author:
vboxsync
Message:

Virtio_1_0,DevVirtioScsi: Converting to new PDM model - split up structures. (untested) bugref:9218

Location:
trunk/src/VBox/Devices
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp

    r81663 r81675  
    338338
    339339/**
    340  * Worker thread context
     340 * Worker thread context, shared state.
    341341 */
    342342typedef struct VIRTIOSCSIWORKER
    343343{
     344    SUPSEMEVENT                     hEvtProcess;                /**< handle of associated sleep/wake-up semaphore      */
     345} VIRTIOSCSIWORKER;
     346/** Pointer to a VirtIO SCSI worker. */
     347typedef VIRTIOSCSIWORKER *PVIRTIOSCSIWORKER;
     348
     349/**
     350 * Worker thread context, ring-3 state.
     351 */
     352typedef struct VIRTIOSCSIWORKERR3
     353{
    344354    R3PTRTYPE(PPDMTHREAD)           pThread;                    /**< pointer to worker thread's handle                 */
    345     SUPSEMEVENT                     hEvtProcess;                /**< handle of associated sleep/wake-up semaphore      */
    346     bool                            fSleeping;                  /**< Flags whether worker thread is sleeping or not    */
    347     bool                            fNotified;                  /**< Flags whether worker thread notified              */
    348 } VIRTIOSCSIWORKER;
    349 typedef VIRTIOSCSIWORKER *PVIRTIOSCSIWORKER;
     355    bool volatile                   fSleeping;                  /**< Flags whether worker thread is sleeping or not    */
     356    bool volatile                   fNotified;                  /**< Flags whether worker thread notified              */
     357} VIRTIOSCSIWORKERR3;
     358/** Pointer to a VirtIO SCSI worker. */
     359typedef VIRTIOSCSIWORKERR3 *PVIRTIOSCSIWORKERR3;
     360
    350361
    351362/**
     
    354365typedef struct VIRTIOSCSITARGET
    355366{
    356     /** Pointer to PCI device that owns this target instance. - R3 pointer */
    357     R3PTRTYPE(struct VIRTIOSCSI *)  pVirtioScsi;
     367    /** The ring-3 device instance so we can easily get our bearings. */
     368    PPDMDEVINSR3                    pDevIns;
    358369
    359370    /** Pointer to attached driver's base interface. */
     
    361372
    362373    /** Target number (PDM LUN) */
    363     RTUINT                          iTarget;
     374    uint32_t                        iTarget;
    364375
    365376    /** Target Description */
    366     char *                          pszTargetName;
     377    R3PTRTYPE(char *)               pszTargetName;
    367378
    368379    /** Target base interface. */
     
    407418
    408419/**
    409  * PDM instance data (state) for VirtIO Host SCSI device
     420 * VirtIO Host SCSI device state, shared edition.
    410421 *
    411  * @extends     PDMPCIDEV
     422 * @extends     VIRTIOSTATE
    412423 */
    413424typedef struct VIRTIOSCSI
     
    417428
    418429    bool                            fBootable;
    419     bool                            afPadding[3];
     430    bool                            afPadding0[3];
    420431
    421432    /** Number of targets in paTargetInstances. */
    422433    uint32_t                        cTargets;
     434
     435    /** Per device-bound virtq worker-thread contexts (eventq slot unused) */
     436    VIRTIOSCSIWORKER                aWorkers[VIRTIOSCSI_QUEUE_CNT];
     437
     438    /** Instance name */
     439    char                            szInstance[16];
     440
     441    /** Device-specific spec-based VirtIO queuenames */
     442    char                            aszQueueNames[VIRTIOSCSI_QUEUE_CNT][VIRTIO_MAX_QUEUE_NAME_SIZE];
     443
     444    /** Track which VirtIO queues we've attached to */
     445    bool                            afQueueAttached[VIRTIOSCSI_QUEUE_CNT];
     446
     447    /** Set if events missed due to lack of bufs avail on eventq */
     448    bool                            fEventsMissed;
     449
     450    /** True if PDMDevHlpAsyncNotificationCompleted should be called when port goes idle
     451     * @todo r=bird: What's this for exactly? It's not referenced anywhere... */
     452    bool volatile                   fSignalIdle;
     453    /** Explicit alignment padding. */
     454    bool                            afPadding1[2];
     455
     456    /** Mask of VirtIO Async Event types this device will deliver */
     457    uint32_t                        fAsyncEvtsEnabled;
     458
     459    /** Total number of requests active across all targets */
     460    volatile uint32_t               cActiveReqs;
     461
     462    /** Events the guest has subscribed to get notifications of */
     463    uint32_t                        fSubscribedEvents;
     464
     465    /** VirtIO Host SCSI device runtime configuration parameters */
     466    VIRTIOSCSI_CONFIG_T             virtioScsiConfig;
     467
     468    /** True if the guest/driver and VirtIO framework are in the ready state */
     469    uint32_t                        fVirtioReady;
     470
     471    /** True if VIRTIO_SCSI_F_T10_PI was negotiated */
     472    uint32_t                        fHasT10pi;
     473
     474    /** True if VIRTIO_SCSI_F_T10_PI was negotiated */
     475    uint32_t                        fHasHotplug;
     476
     477    /** True if VIRTIO_SCSI_F_T10_PI was negotiated */
     478    uint32_t                        fHasInOutBufs;
     479
     480    /** True if VIRTIO_SCSI_F_T10_PI was negotiated */
     481    uint32_t                        fHasLunChange;
     482
     483    /** True if in the process of resetting */
     484    uint32_t                        fResetting;
     485
     486} VIRTIOSCSI;
     487/** Pointer to the shared state of the VirtIO Host SCSI device. */
     488typedef VIRTIOSCSI *PVIRTIOSCSI;
     489
     490
     491/**
     492 * VirtIO Host SCSI device state, ring-3 edition.
     493 *
     494 * @extends     VIRTIOSTATER3
     495 */
     496typedef struct VIRTIOSCSIR3
     497{
     498    /** The virtio ring-3 state. */
     499    VIRTIOSTATER3                   Virtio;
     500
    423501    /** Array of per-target data. */
    424502    R3PTRTYPE(PVIRTIOSCSITARGET)    paTargetInstances;
    425 #if HC_ARCH_BITS == 32
    426     RTR3PTR                         R3PtrPadding0;
    427 #endif
    428503
    429504    /** Per device-bound virtq worker-thread contexts (eventq slot unused) */
    430     VIRTIOSCSIWORKER                aWorkers[VIRTIOSCSI_QUEUE_CNT];
    431 
    432     /** Instance name */
    433     char                            szInstance[16];
    434 
    435     /** Device-specific spec-based VirtIO queuenames */
    436     char                            aszQueueNames[VIRTIOSCSI_QUEUE_CNT][VIRTIO_MAX_QUEUE_NAME_SIZE];
    437 
    438     /** Track which VirtIO queues we've attached to */
    439     bool                            afQueueAttached[VIRTIOSCSI_QUEUE_CNT];
     505    VIRTIOSCSIWORKERR3              aWorkers[VIRTIOSCSI_QUEUE_CNT];
    440506
    441507    /** Device base interface. */
    442508    PDMIBASE                        IBase;
    443509
    444     /** Pointer to the device instance. - R3 ptr. */
    445     PPDMDEVINSR3                    pDevInsR3;
    446 
    447     /** Pointer to the device instance. - R0 ptr. */
    448     PPDMDEVINSR0                    pDevInsR0;
    449 
    450     /** Pointer to the device instance. - RC ptr. */
    451     PPDMDEVINSRC                    pDevInsRC;
     510    /** Pointer to the device instance.
     511     * @note Only used in interface callbacks. */
     512    PPDMDEVINSR3                    pDevIns;
    452513
    453514    /** Status Target: LEDs port interface. */
     
    462523    /** Queue to send tasks to R3. - HC ptr */
    463524    R3PTRTYPE(PPDMQUEUE)            pNotifierQueueR3;
    464 
    465     /** The support driver session handle. */
    466     R3R0PTRTYPE(PSUPDRVSESSION)     pSupDrvSession;
    467 
    468     /** Mask of VirtIO Async Event types this device will deliver */
    469     uint32_t                        fAsyncEvtsEnabled;
    470 
    471     /** Total number of requests active across all targets */
    472     volatile uint32_t               cActiveReqs;
    473 
    474     /** True if PDMDevHlpAsyncNotificationCompleted should be called when port goes idle */
    475     bool volatile                   fSignalIdle;
    476 
    477     /** Events the guest has subscribed to get notifications of */
    478     uint32_t                        fSubscribedEvents;
    479 
    480     /** Set if events missed due to lack of bufs avail on eventq */
    481     bool                            fEventsMissed;
    482 
    483     /** VirtIO Host SCSI device runtime configuration parameters */
    484     VIRTIOSCSI_CONFIG_T             virtioScsiConfig;
    485 
    486     /** True if the guest/driver and VirtIO framework are in the ready state */
    487     uint32_t                        fVirtioReady;
    488 
    489     /** True if VIRTIO_SCSI_F_T10_PI was negotiated */
    490     uint32_t                        fHasT10pi;
    491 
    492     /** True if VIRTIO_SCSI_F_T10_PI was negotiated */
    493     uint32_t                        fHasHotplug;
    494 
    495     /** True if VIRTIO_SCSI_F_T10_PI was negotiated */
    496     uint32_t                        fHasInOutBufs;
    497 
    498     /** True if VIRTIO_SCSI_F_T10_PI was negotiated */
    499     uint32_t                        fHasLunChange;
    500 
    501     /** True if in the process of resetting */
    502     uint32_t                        fResetting;
    503525
    504526    /** True if in the process of quiescing I/O */
     
    507529    VIRTIOSCSIQUIESCINGFOR          enmQuiescingFor;
    508530
    509 } VIRTIOSCSI, *PVIRTIOSCSI;
     531} VIRTIOSCSIR3;
     532/** Pointer to the ring-3 state of the VirtIO Host SCSI device. */
     533typedef VIRTIOSCSIR3 *PVIRTIOSCSIR3;
     534
     535
     536/**
     537 * VirtIO Host SCSI device state, ring-0 edition.
     538 */
     539typedef struct VIRTIOSCSIR0
     540{
     541    /** The virtio ring-0 state. */
     542    VIRTIOSTATER0                   Virtio;
     543} VIRTIOSCSIR0;
     544/** Pointer to the ring-0 state of the VirtIO Host SCSI device. */
     545typedef VIRTIOSCSIR0 *PVIRTIOSCSIR0;
     546
     547
     548/**
     549 * VirtIO Host SCSI device state, raw-mode edition.
     550 */
     551typedef struct VIRTIOSCSIRC
     552{
     553    /** The virtio raw-mode state. */
     554    VIRTIOSTATERC                   Virtio;
     555} VIRTIOSCSIRC;
     556/** Pointer to the ring-0 state of the VirtIO Host SCSI device. */
     557typedef VIRTIOSCSIRC *PVIRTIOSCSIRC;
     558
     559
     560/** @typedef VIRTIOSCSICC
     561 * The instance data for the current context. */
     562typedef CTX_SUFF(VIRTIOSCSI) VIRTIOSCSICC;
     563/** @typedef PVIRTIOSCSICC
     564 * Pointer to the instance data for the current context. */
     565typedef CTX_SUFF(PVIRTIOSCSI) PVIRTIOSCSICC;
     566
    510567
    511568/**
     
    613670#endif /* LOG_ENABLED */
    614671
    615 static int virtioScsiR3SendEvent(PVIRTIOSCSI pThis, uint16_t uTarget, uint32_t uEventType, uint32_t uReason)
     672static int virtioScsiR3SendEvent(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget, uint32_t uEventType, uint32_t uReason)
    616673{
    617674
     
    671728    }
    672729
    673     if (virtioQueueIsEmpty(&pThis->Virtio, EVENTQ_IDX))
     730    if (virtioQueueIsEmpty(pDevIns, &pThis->Virtio, EVENTQ_IDX))
    674731    {
    675732        LogFunc(("eventq is empty, events missed (driver didn't preload queue)!\n"));
     
    679736
    680737    PVIRTIO_DESC_CHAIN_T pDescChain;
    681     virtioR3QueueGet(&pThis->Virtio, EVENTQ_IDX, &pDescChain, true);
     738    virtioR3QueueGet(pDevIns, &pThis->Virtio, EVENTQ_IDX, &pDescChain, true);
    682739
    683740    RTSGBUF reqSegBuf;
     
    685742    RTSgBufInit(&reqSegBuf, aReqSegs, RT_ELEMENTS(aReqSegs));
    686743
    687     virtioR3QueuePut( &pThis->Virtio, EVENTQ_IDX, &reqSegBuf, pDescChain, true);
    688     virtioQueueSync(&pThis->Virtio, EVENTQ_IDX);
     744    virtioR3QueuePut(pDevIns, &pThis->Virtio, EVENTQ_IDX, &reqSegBuf, pDescChain, true);
     745    virtioQueueSync(pDevIns, &pThis->Virtio, EVENTQ_IDX);
    689746
    690747    return VINF_SUCCESS;
     
    702759 * This is called to complete a request immediately
    703760 *
    704  * @param   pThis       PDM driver instance state
     761 * @param   pDevIns     The device instance.
     762 * @param   pThis       VirtIO SCSI shared instance data.
     763 * @param   pThisCC     VirtIO SCSI ring-3 instance data.
    705764 * @param   qIdx        Queue index
    706765 * @param   pDescChain  Pointer to pre-processed descriptor chain pulled from virtq
     
    710769 * @returns VBox status code.
    711770 */
    712 static int virtioScsiR3ReqErr(PVIRTIOSCSI pThis, uint16_t qIdx, PVIRTIO_DESC_CHAIN_T pDescChain,
    713                               REQ_RESP_HDR_T *pRespHdr, uint8_t *pbSense)
     771static int virtioScsiR3ReqErr(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, uint16_t qIdx,
     772                              PVIRTIO_DESC_CHAIN_T pDescChain, REQ_RESP_HDR_T *pRespHdr, uint8_t *pbSense)
    714773{
    715774    uint8_t *pabSenseBuf = (uint8_t *)RTMemAllocZ(pThis->virtioScsiConfig.uSenseSize);
     
    735794        pRespHdr->uResponse = VIRTIOSCSI_S_RESET;
    736795
    737     virtioR3QueuePut(&pThis->Virtio, qIdx, &reqSegBuf, pDescChain, true /* fFence */);
    738     virtioQueueSync(&pThis->Virtio, qIdx);
     796    virtioR3QueuePut(pDevIns, &pThis->Virtio, qIdx, &reqSegBuf, pDescChain, true /* fFence */);
     797    virtioQueueSync(pDevIns, &pThis->Virtio, qIdx);
    739798
    740799    RTMemFree(pabSenseBuf);
    741800
    742     if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThis->fQuiescing)
    743         PDMDevHlpAsyncNotificationCompleted(pThis->CTX_SUFF(pDevIns));
     801    if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThisCC->fQuiescing)
     802        PDMDevHlpAsyncNotificationCompleted(pDevIns);
    744803
    745804    Log2(("---------------------------------------------------------------------------------\n"));
     
    779838                                                 void *pvIoReqAlloc, int rcReq)
    780839{
    781     RT_NOREF(pInterface);
    782 
    783     PVIRTIOSCSIREQ    pReq      = (PVIRTIOSCSIREQ)pvIoReqAlloc;
    784     PVIRTIOSCSITARGET pTarget   = pReq->pTarget;
    785     PVIRTIOSCSI       pThis     = pTarget->pVirtioScsi;
    786     PPDMIMEDIAEX      pIMediaEx = pTarget->pDrvMediaEx;
     840    PVIRTIOSCSITARGET   pTarget   = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort);
     841    PPDMDEVINS          pDevIns   = pTarget->pDevIns;
     842    PVIRTIOSCSI         pThis     = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     843    PVIRTIOSCSICC       pThisCC   = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
     844    PPDMIMEDIAEX        pIMediaEx = pTarget->pDrvMediaEx;
     845    PVIRTIOSCSIREQ      pReq      = (PVIRTIOSCSIREQ)pvIoReqAlloc;
    787846
    788847    size_t cbResidual = 0;
     
    866925        respHdr.uResidual  = pReq->cbDataIn;
    867926
    868         virtioScsiR3ReqErr(pThis, pReq->qIdx, pReq->pDescChain, &respHdr, abSense);
     927        virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, pReq->qIdx, pReq->pDescChain, &respHdr, abSense);
    869928    }
    870929    else
     
    891950
    892951
    893         virtioR3QueuePut(&pThis->Virtio, pReq->qIdx, &reqSegBuf, pReq->pDescChain, true /* fFence TBD */);
    894         virtioQueueSync(&pThis->Virtio, pReq->qIdx);
     952        virtioR3QueuePut(pDevIns, &pThis->Virtio, pReq->qIdx, &reqSegBuf, pReq->pDescChain, true /* fFence TBD */);
     953        virtioQueueSync(pDevIns, &pThis->Virtio, pReq->qIdx);
    895954
    896955
     
    900959    virtioScsiR3FreeReq(pTarget, pReq);
    901960
    902     if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThis->fQuiescing)
    903         PDMDevHlpAsyncNotificationCompleted(pThis->CTX_SUFF(pDevIns));
     961    if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThisCC->fQuiescing)
     962        PDMDevHlpAsyncNotificationCompleted(pDevIns);
    904963
    905964    return VINF_SUCCESS;
     
    914973                                                      void *pvIoReqAlloc, uint32_t offDst, PRTSGBUF pSgBuf, size_t cbCopy)
    915974{
     975    PVIRTIOSCSITARGET   pTarget   = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort);
     976    PPDMDEVINS          pDevIns   = pTarget->pDevIns;
     977    PVIRTIOSCSIREQ      pReq      = (PVIRTIOSCSIREQ)pvIoReqAlloc;
    916978    RT_NOREF(hIoReq, cbCopy);
    917 
    918     PVIRTIOSCSIREQ pReq = (PVIRTIOSCSIREQ)pvIoReqAlloc;
    919979
    920980    if (!pReq->cbDataIn)
    921981        return VINF_SUCCESS;
    922 
    923     PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort);
    924     PVIRTIOSCSI pThis = pTarget->pVirtioScsi;
    925982
    926983    AssertReturn(pReq->pDescChain, VERR_INVALID_PARAMETER);
     
    942999        uint64_t dstSgCur   = (uint64_t)pSgPhysReturn->pvSegCur;
    9431000        cbCopied = RT_MIN((uint64_t)pSgBuf->cbSegLeft, dstSgLen - (dstSgCur - dstSgStart));
    944         PDMDevHlpPhysWrite(pThis->CTX_SUFF(pDevIns),
    945                           (RTGCPHYS)pSgPhysReturn->pvSegCur, pSgBuf->pvSegCur, cbCopied);
     1001        PDMDevHlpPhysWrite(pDevIns, (RTGCPHYS)pSgPhysReturn->pvSegCur, pSgBuf->pvSegCur, cbCopied);
    9461002        RTSgBufAdvance(pSgBuf, cbCopied);
    9471003        RTSgBufAdvance(pSgPhysReturn, cbCopied);
     
    9641020                                                    void *pvIoReqAlloc, uint32_t offSrc, PRTSGBUF pSgBuf, size_t cbCopy)
    9651021{
     1022    PVIRTIOSCSITARGET   pTarget   = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort);
     1023    PPDMDEVINS          pDevIns   = pTarget->pDevIns;
     1024    PVIRTIOSCSIREQ      pReq      = (PVIRTIOSCSIREQ)pvIoReqAlloc;
    9661025    RT_NOREF(hIoReq, cbCopy);
    967 
    968     PVIRTIOSCSIREQ pReq = (PVIRTIOSCSIREQ)pvIoReqAlloc;
    9691026
    9701027    if (!pReq->cbDataOut)
    9711028        return VINF_SUCCESS;
    972 
    973     PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort);
    974     PVIRTIOSCSI pThis = pTarget->pVirtioScsi;
    9751029
    9761030    PRTSGBUF pSgPhysSend = pReq->pDescChain->pSgPhysSend;
     
    9861040        uint64_t srcSgCur   = (uint64_t)pSgPhysSend->pvSegCur;
    9871041        cbCopied = RT_MIN((uint64_t)pSgBuf->cbSegLeft, srcSgLen - (srcSgCur - srcSgStart));
    988         PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns),
     1042        PDMDevHlpPhysRead(pDevIns,
    9891043                          (RTGCPHYS)pSgPhysSend->pvSegCur, pSgBuf->pvSegCur, cbCopied);
    9901044        RTSgBufAdvance(pSgBuf, cbCopied);
     
    10041058static DECLCALLBACK(void) virtioScsiR3MediumEjected(PPDMIMEDIAEXPORT pInterface)
    10051059{
    1006     PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort);
    1007     PVIRTIOSCSI pThis = pTarget->pVirtioScsi;
     1060    PVIRTIOSCSITARGET   pTarget   = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort);
     1061    PPDMDEVINS          pDevIns   = pTarget->pDevIns;
     1062    PVIRTIOSCSICC       pThisCC   = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
     1063
    10081064    LogFunc(("LUN %d Ejected!\n", pTarget->iTarget));
    1009     if (pThis->pMediaNotify)
    1010     {
    1011         int rc = VMR3ReqCallNoWait(PDMDevHlpGetVM(pThis->CTX_SUFF(pDevIns)), VMCPUID_ANY,
    1012                                    (PFNRT)pThis->pMediaNotify->pfnEjected, 2,
    1013                                    pThis->pMediaNotify, pTarget->iTarget);
     1065    if (pThisCC->pMediaNotify)
     1066    {
     1067        int rc = VMR3ReqCallNoWait(PDMDevHlpGetVM(pDevIns), VMCPUID_ANY,
     1068                                   (PFNRT)pThisCC->pMediaNotify->pfnEjected, 2,
     1069                                   pThisCC->pMediaNotify, pTarget->iTarget);
    10141070        AssertRC(rc);
    10151071    }
     
    10221078                                                        void *pvIoReqAlloc, PDMMEDIAEXIOREQSTATE enmState)
    10231079{
    1024     RT_NOREF4(pInterface, hIoReq, pvIoReqAlloc, enmState);
    1025     PVIRTIOSCSI pThis = RT_FROM_MEMBER(pInterface, VIRTIOSCSI, IBase);
     1080    PVIRTIOSCSITARGET   pTarget   = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort);
     1081    PPDMDEVINS          pDevIns   = pTarget->pDevIns;
     1082    PVIRTIOSCSI         pThis     = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     1083    PVIRTIOSCSICC       pThisCC   = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
     1084    RT_NOREF(hIoReq, pvIoReqAlloc);
    10261085
    10271086    switch (enmState)
     
    10301089        {
    10311090            /* Stop considering this request active */
    1032             if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThis->fQuiescing)
    1033                 PDMDevHlpAsyncNotificationCompleted(pThis->CTX_SUFF(pDevIns));
     1091            if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThisCC->fQuiescing)
     1092                PDMDevHlpAsyncNotificationCompleted(pDevIns);
    10341093            break;
    10351094        }
     
    10521111 * @returns VBox status code (logged by caller).
    10531112 */
    1054 static int virtioScsiR3ReqSubmit(PVIRTIOSCSI pThis, uint16_t qIdx, PVIRTIO_DESC_CHAIN_T pDescChain)
     1113static int virtioScsiR3ReqSubmit(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC,
     1114                                 uint16_t qIdx, PVIRTIO_DESC_CHAIN_T pDescChain)
    10551115{
    10561116    AssertReturn(pDescChain->cbPhysSend, VERR_INVALID_PARAMETER);
     
    10691129        size_t cbSeg = cb;
    10701130        RTGCPHYS GCPhys = (RTGCPHYS)RTSgBufGetNextSegment(pDescChain->pSgPhysSend, &cbSeg);
    1071         PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), GCPhys, pb, cbSeg);
     1131        PDMDevHlpPhysRead(pDevIns, GCPhys, pb, cbSeg);
    10721132        pb += cbSeg;
    10731133        cb -= cbSeg;
     
    10761136    uint8_t  uTarget  = pVirtqReq->ReqHdr.abVirtioLun[1];
    10771137    uint32_t uScsiLun = (pVirtqReq->ReqHdr.abVirtioLun[2] << 8 | pVirtqReq->ReqHdr.abVirtioLun[3]) & 0x3fff;
    1078     PVIRTIOSCSITARGET pTarget = &pThis->paTargetInstances[uTarget];
    10791138
    10801139    LogFunc(("[%s] (Target: %d LUN: %d)  CDB: %.*Rhxs\n",
     
    10921151    uint32_t cbDataOut = pDescChain->cbPhysSend - uDataOutOff;
    10931152    uint32_t cbDataIn  = pDescChain->cbPhysReturn - uDataInOff;
     1153
    10941154    /*
    10951155     * Handle submission errors
    10961156     */
    1097 
    1098     if (RT_UNLIKELY(pThis->fResetting))
     1157/** @todo r=bird: RT_UNLIKELY doesn't work everywhere and is deprecated, convert to RT_LIKELY like in the first instance here. */
     1158    if (RT_LIKELY(!pThis->fResetting))
     1159    { /*  likely */ }
     1160    else
    10991161    {
    11001162        Log2Func(("Aborting req submission because reset is in progress\n"));
     
    11041166        respHdr.uResponse  = VIRTIOSCSI_S_RESET;
    11051167        respHdr.uResidual  = cbDataIn + cbDataOut;
    1106         virtioScsiR3ReqErr(pThis, qIdx, pDescChain, &respHdr, NULL);
     1168        virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, NULL);
    11071169        RTMemFree(pVirtqReq);
    11081170        return VINF_SUCCESS;
     
    11191181        respHdr.uResponse  = VIRTIOSCSI_S_OK;
    11201182        respHdr.uResidual  = cbDataOut + cbDataIn;
    1121         virtioScsiR3ReqErr(pThis, qIdx, pDescChain, &respHdr, abSense);
     1183        virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense);
    11221184        RTMemFree(pVirtqReq);
    11231185        return VINF_SUCCESS;
    11241186    }
    1125     if (RT_UNLIKELY(uTarget >= pThis->cTargets || !pTarget->fPresent))
     1187
     1188    if (RT_UNLIKELY(   uTarget >= pThis->cTargets
     1189                    || !pThisCC->paTargetInstances[uTarget].fPresent
     1190                    || !pThisCC->paTargetInstances[uTarget].pDrvMediaEx))
    11261191    {
    11271192        Log2Func(("Error submitting request, target not present!!\n"));
     
    11331198        respHdr.uResponse  = VIRTIOSCSI_S_BAD_TARGET;
    11341199        respHdr.uResidual  = cbDataIn + cbDataOut;
    1135         virtioScsiR3ReqErr(pThis, qIdx, pDescChain, &respHdr , abSense);
     1200        virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr , abSense);
    11361201        RTMemFree(pVirtqReq);
    11371202        return VINF_SUCCESS;
    11381203    }
     1204    PVIRTIOSCSITARGET pTarget = &pThisCC->paTargetInstances[uTarget];
     1205
    11391206    if (RT_UNLIKELY(cbDataIn && cbDataOut && !pThis->fHasInOutBufs)) /* VirtIO 1.0, 5.6.6.1.1 */
    11401207    {
     
    11471214        respHdr.uResponse  = VIRTIOSCSI_S_FAILURE;
    11481215        respHdr.uResidual  = cbDataIn + cbDataOut;
    1149         virtioScsiR3ReqErr(pThis, qIdx, pDescChain, &respHdr , abSense);
     1216        virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr , abSense);
    11501217        RTMemFree(pVirtqReq);
    11511218        return VINF_SUCCESS;
     
    12171284        respHdr.uResponse  = VIRTIOSCSI_S_FAILURE;
    12181285        respHdr.uResidual  = cbDataIn + cbDataOut;
    1219         virtioScsiR3ReqErr(pThis, qIdx, pDescChain, &respHdr, abSense);
     1286        virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense);
    12201287        virtioScsiR3FreeReq(pTarget, pReq);
    12211288    }
     
    12291296 *
    12301297 * @returns VBox status code (ignored by the caller).
    1231  * @param   pThis       The device instance data.
     1298 * @param   pDevIns     The device instance.
     1299 * @param   pThis       VirtIO SCSI shared instance data.
     1300 * @param   pThisCC     VirtIO SCSI ring-3 instance data.
    12321301 * @param   qIdx        CONTROLQ_IDX
    12331302 * @param   pDescChain  Descriptor chain to process.
    12341303 */
    1235 static int virtioScsiR3Ctrl(PVIRTIOSCSI pThis, uint16_t qIdx, PVIRTIO_DESC_CHAIN_T pDescChain)
     1304static int virtioScsiR3Ctrl(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC,
     1305                            uint16_t qIdx, PVIRTIO_DESC_CHAIN_T pDescChain)
    12361306{
    12371307    uint8_t bResponse = VIRTIOSCSI_S_OK;
     
    12621332        AssertCompile(sizeof(RTGCPHYS) == sizeof(void *)); /* ASSUMING RTGCPHYS and host pointers are interchangable. (horrible!) */
    12631333        RTGCPHYS GCPhys = (RTGCPHYS)RTSgBufGetNextSegment(pDescChain->pSgPhysSend, &cbSeg);
    1264         PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), GCPhys, pb, cbSeg);
     1334        PDMDevHlpPhysRead(pDevIns, GCPhys, pb, cbSeg);
    12651335        pb += cbSeg;
    12661336        cb -= cbSeg;
     
    12891359                      QUEUENAME(qIdx), uTarget, uScsiLun, virtioGetTMFTypeText(pScsiCtrlUnion->scsiCtrlTmf.uSubtype)));
    12901360
    1291             PVIRTIOSCSITARGET pTarget = NULL;
    1292             if (uTarget < pThis->cTargets)
    1293                 pTarget = &pThis->paTargetInstances[uTarget];
    1294 
    1295             if (uTarget >= pThis->cTargets || !pTarget->fPresent)
     1361            if (uTarget >= pThis->cTargets || !pThisCC->paTargetInstances[uTarget].fPresent)
    12961362                bResponse = VIRTIOSCSI_S_BAD_TARGET;
    12971363            else
     
    13451411            uint32_t uScsiLun = (pScsiCtrlAnQuery->abScsiLun[2] << 8 | pScsiCtrlAnQuery->abScsiLun[3]) & 0x3fff;
    13461412
    1347             PVIRTIOSCSITARGET pTarget = NULL;
    1348             if (uTarget < pThis->cTargets)
    1349                 pTarget = &pThis->paTargetInstances[uTarget];
    1350 
    1351             if (uTarget >= pThis->cTargets || !pTarget->fPresent)
     1413            if (uTarget >= pThis->cTargets || !pThisCC->paTargetInstances[uTarget].fPresent)
    13521414                bResponse = VIRTIOSCSI_S_BAD_TARGET;
    13531415            else
     
    13951457            }
    13961458#endif
    1397 
    1398             PVIRTIOSCSITARGET pTarget = NULL;
    1399             if (uTarget < pThis->cTargets)
    1400                 pTarget = &pThis->paTargetInstances[uTarget];
    1401 
    1402             if (uTarget >= pThis->cTargets || !pTarget->fPresent)
     1459            if (uTarget >= pThis->cTargets || !pThisCC->paTargetInstances[uTarget].fPresent)
    14031460                bResponse = VIRTIOSCSI_S_BAD_TARGET;
    14041461            else
     
    14331490
    14341491    LogFunc(("Response code: %s\n", virtioGetReqRespText(bResponse)));
    1435     virtioR3QueuePut( &pThis->Virtio, qIdx, &reqSegBuf, pDescChain, true);
    1436     virtioQueueSync(&pThis->Virtio, qIdx);
     1492    virtioR3QueuePut(pDevIns, &pThis->Virtio, qIdx, &reqSegBuf, pDescChain, true);
     1493    virtioQueueSync(pDevIns, &pThis->Virtio, qIdx);
    14371494
    14381495    return VINF_SUCCESS;
     
    14441501static DECLCALLBACK(int) virtioScsiR3WorkerWakeUp(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
    14451502{
    1446     RT_NOREF(pThread);
    1447     uint16_t qIdx = ((uint64_t)pThread->pvUser) & 0xffff;
    14481503    PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
    1449     return SUPSemEventSignal(pThis->pSupDrvSession, pThis->aWorkers[qIdx].hEvtProcess);
     1504    return PDMDevHlpSUPSemEventSignal(pDevIns, pThis->aWorkers[(uintptr_t)pThread->pvUser].hEvtProcess);
    14501505}
    14511506
     
    14551510static DECLCALLBACK(int) virtioScsiR3WorkerThread(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
    14561511{
    1457     uint16_t const qIdx = (uint16_t)(uintptr_t)pThread->pvUser;
    1458     PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
    1459     PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[qIdx];
     1512    uint16_t const      qIdx      = (uint16_t)(uintptr_t)pThread->pvUser;
     1513    PVIRTIOSCSI         pThis     = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     1514    PVIRTIOSCSICC       pThisCC   = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
     1515    PVIRTIOSCSIWORKER   pWorker   = &pThis->aWorkers[qIdx];
     1516    PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[qIdx];
    14601517
    14611518    if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
     
    14641521    while (pThread->enmState == PDMTHREADSTATE_RUNNING)
    14651522    {
    1466         if (virtioQueueIsEmpty(&pThis->Virtio, qIdx))
     1523        if (virtioQueueIsEmpty(pDevIns, &pThis->Virtio, qIdx))
    14671524        {
    14681525            /* Atomic interlocks avoid missing alarm while going to sleep & notifier waking the awoken */
    1469             ASMAtomicWriteBool(&pWorker->fSleeping, true);
    1470             bool fNotificationSent = ASMAtomicXchgBool(&pWorker->fNotified, false);
     1526            ASMAtomicWriteBool(&pWorkerR3->fSleeping, true);
     1527            bool fNotificationSent = ASMAtomicXchgBool(&pWorkerR3->fNotified, false);
    14711528            if (!fNotificationSent)
    14721529            {
    14731530                Log6Func(("%s worker sleeping...\n", QUEUENAME(qIdx)));
    1474                 Assert(ASMAtomicReadBool(&pWorker->fSleeping));
    1475                 int rc = SUPSemEventWaitNoResume(pThis->pSupDrvSession, pWorker->hEvtProcess, RT_INDEFINITE_WAIT);
     1531                Assert(ASMAtomicReadBool(&pWorkerR3->fSleeping));
     1532                int rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pWorker->hEvtProcess, RT_INDEFINITE_WAIT);
    14761533                AssertLogRelMsgReturn(RT_SUCCESS(rc) || rc == VERR_INTERRUPTED, ("%Rrc\n", rc), rc);
    14771534                if (RT_UNLIKELY(pThread->enmState != PDMTHREADSTATE_RUNNING))
    14781535                    return VINF_SUCCESS;
    14791536                Log6Func(("%s worker woken\n", QUEUENAME(qIdx)));
    1480                 ASMAtomicWriteBool(&pWorker->fNotified, false);
     1537                ASMAtomicWriteBool(&pWorkerR3->fNotified, false);
    14811538            }
    1482             ASMAtomicWriteBool(&pWorker->fSleeping, false);
     1539            ASMAtomicWriteBool(&pWorkerR3->fSleeping, false);
    14831540        }
    14841541
     
    14881545            break;
    14891546        }
    1490         if (!pThis->fQuiescing)
     1547        if (!pThisCC->fQuiescing)
    14911548        {
    14921549             Log6Func(("fetching next descriptor chain from %s\n", QUEUENAME(qIdx)));
    14931550             PVIRTIO_DESC_CHAIN_T pDescChain;
    1494              int rc = virtioR3QueueGet(&pThis->Virtio, qIdx, &pDescChain, true);
     1551             int rc = virtioR3QueueGet(pDevIns, &pThis->Virtio, qIdx, &pDescChain, true);
    14951552             if (rc == VERR_NOT_AVAILABLE)
    14961553             {
     
    15011558             AssertRC(rc);
    15021559             if (qIdx == CONTROLQ_IDX)
    1503                  virtioScsiR3Ctrl(pThis, qIdx, pDescChain);
     1560                 virtioScsiR3Ctrl(pDevIns, pThis, pThisCC, qIdx, pDescChain);
    15041561             else /* request queue index */
    15051562             {
    1506                   rc = virtioScsiR3ReqSubmit(pThis, qIdx, pDescChain);
     1563                  rc = virtioScsiR3ReqSubmit(pDevIns, pThis, pThisCC, qIdx, pDescChain);
    15071564                  if (RT_FAILURE(rc))
    15081565                  {
     
    15201577*********************************************************************************************************************************/
    15211578
    1522 DECLINLINE(void) virtioScsiR3ReportEventsMissed(PVIRTIOSCSI pThis, uint16_t uTarget)
    1523 {
    1524     virtioScsiR3SendEvent(pThis, uTarget, VIRTIOSCSI_T_NO_EVENT | VIRTIOSCSI_T_EVENTS_MISSED, 0);
     1579DECLINLINE(void) virtioScsiR3ReportEventsMissed(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget)
     1580{
     1581    virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_NO_EVENT | VIRTIOSCSI_T_EVENTS_MISSED, 0);
    15251582}
    15261583
     
    15301587 * This effectively removes the SCSI Target/LUN on the guest side
    15311588 */
    1532 DECLINLINE(void) virtioScsiR3ReportTargetRemoved(PVIRTIOSCSI pThis, uint16_t uTarget)
     1589DECLINLINE(void) virtioScsiR3ReportTargetRemoved(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget)
    15331590{
    15341591    if (pThis->fHasHotplug)
    1535         virtioScsiR3SendEvent(pThis, uTarget, VIRTIOSCSI_T_TRANSPORT_RESET, VIRTIOSCSI_EVT_RESET_REMOVED);
     1592        virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_TRANSPORT_RESET, VIRTIOSCSI_EVT_RESET_REMOVED);
    15361593}
    15371594
     
    15391596 * This effectively adds the SCSI Target/LUN on the guest side
    15401597 */
    1541 DECLINLINE(void) virtioScsiR3ReportTargetAdded(PVIRTIOSCSI pThis, uint16_t uTarget)
     1598DECLINLINE(void) virtioScsiR3ReportTargetAdded(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget)
    15421599{
    15431600    if (pThis->fHasHotplug)
    1544         virtioScsiR3SendEvent(pThis, uTarget, VIRTIOSCSI_T_TRANSPORT_RESET, VIRTIOSCSI_EVT_RESET_RESCAN);
    1545 }
    1546 
    1547 DECLINLINE(void) virtioScsiR3ReportTargetReset(PVIRTIOSCSI pThis, uint16_t uTarget)
    1548 {
    1549     virtioScsiR3SendEvent(pThis, uTarget, VIRTIOSCSI_T_TRANSPORT_RESET, VIRTIOSCSI_EVT_RESET_HARD);
    1550 }
    1551 
    1552 DECLINLINE(void) virtioScsiR3ReportOperChange(PVIRTIOSCSI pThis, uint16_t uTarget)
     1601        virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_TRANSPORT_RESET, VIRTIOSCSI_EVT_RESET_RESCAN);
     1602}
     1603
     1604DECLINLINE(void) virtioScsiR3ReportTargetReset(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget)
     1605{
     1606    virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_TRANSPORT_RESET, VIRTIOSCSI_EVT_RESET_HARD);
     1607}
     1608
     1609DECLINLINE(void) virtioScsiR3ReportOperChange(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget)
    15531610{
    15541611    if (pThis->fSubscribedEvents & VIRTIOSCSI_EVT_ASYNC_OPERATIONAL_CHANGE)
    1555         virtioScsiR3SendEvent(pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_OPERATIONAL_CHANGE);
    1556 }
    1557 
    1558 DECLINLINE(void) virtioScsiR3ReportPowerMsg(PVIRTIOSCSI pThis, uint16_t uTarget)
     1612        virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_OPERATIONAL_CHANGE);
     1613}
     1614
     1615DECLINLINE(void) virtioScsiR3ReportPowerMsg(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget)
    15591616{
    15601617    if (pThis->fSubscribedEvents & VIRTIOSCSI_EVT_ASYNC_POWER_MGMT)
    1561         virtioScsiR3SendEvent(pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_POWER_MGMT);
    1562 }
    1563 
    1564 DECLINLINE(void) virtioScsiR3ReportExtReq(PVIRTIOSCSI pThis, uint16_t uTarget)
     1618        virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_POWER_MGMT);
     1619}
     1620
     1621DECLINLINE(void) virtioScsiR3ReportExtReq(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget)
    15651622{
    15661623    if (pThis->fSubscribedEvents & VIRTIOSCSI_EVT_ASYNC_EXTERNAL_REQUEST)
    1567         virtioScsiR3SendEvent(pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_EXTERNAL_REQUEST);
    1568 }
    1569 
    1570 DECLINLINE(void) virtioScsiR3ReportMediaChange(PVIRTIOSCSI pThis, uint16_t uTarget)
     1624        virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_EXTERNAL_REQUEST);
     1625}
     1626
     1627DECLINLINE(void) virtioScsiR3ReportMediaChange(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget)
    15711628{
    15721629    if (pThis->fSubscribedEvents & VIRTIOSCSI_EVT_ASYNC_MEDIA_CHANGE)
    1573         virtioScsiR3SendEvent(pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_MEDIA_CHANGE);
    1574 }
    1575 
    1576 DECLINLINE(void) virtioScsiR3ReportMultiHost(PVIRTIOSCSI pThis, uint16_t uTarget)
     1630        virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_MEDIA_CHANGE);
     1631}
     1632
     1633DECLINLINE(void) virtioScsiR3ReportMultiHost(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget)
    15771634{
    15781635    if (pThis->fSubscribedEvents & VIRTIOSCSI_EVT_ASYNC_MULTI_HOST)
    1579         virtioScsiR3SendEvent(pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_MULTI_HOST);
    1580 }
    1581 
    1582 DECLINLINE(void) virtioScsiR3ReportDeviceBusy(PVIRTIOSCSI pThis, uint16_t uTarget)
     1636        virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_MULTI_HOST);
     1637}
     1638
     1639DECLINLINE(void) virtioScsiR3ReportDeviceBusy(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSI pThis, uint16_t uTarget)
    15831640{
    15841641    if (pThis->fSubscribedEvents & VIRTIOSCSI_EVT_ASYNC_DEVICE_BUSY)
    1585         virtioScsiR3SendEvent(pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_DEVICE_BUSY);
    1586 }
    1587 
    1588 DECLINLINE(void) virtioScsiR3ReportParamChange(PVIRTIOSCSI pThis, uint16_t uTarget, uint32_t uSenseCode, uint32_t uSenseQualifier)
     1642        virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_DEVICE_BUSY);
     1643}
     1644
     1645DECLINLINE(void) virtioScsiR3ReportParamChange(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget,
     1646                                               uint32_t uSenseCode, uint32_t uSenseQualifier)
    15891647{
    15901648    uint32_t uReason = uSenseQualifier << 8 | uSenseCode;
    1591     virtioScsiR3SendEvent(pThis, uTarget, VIRTIOSCSI_T_PARAM_CHANGE, uReason);
     1649    virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_PARAM_CHANGE, uReason);
    15921650
    15931651}
     
    15981656 * @callback_method_impl{FNVIRTIOQUEUENOTIFIED}
    15991657 */
    1600 static DECLCALLBACK(void) virtioScsiR3Notified(PVIRTIOSTATE pVirtio, uint16_t qIdx)
    1601 {
     1658static DECLCALLBACK(void) virtioScsiR3Notified(PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC, uint16_t qIdx)
     1659{
     1660    PVIRTIOSCSI         pThis     = RT_FROM_MEMBER(pVirtio, VIRTIOSCSI, Virtio);
     1661    PVIRTIOSCSICC       pThisCC   = RT_FROM_MEMBER(pVirtioCC, VIRTIOSCSICC, Virtio);
     1662    PPDMDEVINS          pDevIns   = pThisCC->pDevIns;
    16021663    AssertReturnVoid(qIdx < VIRTIOSCSI_QUEUE_CNT);
    1603     PVIRTIOSCSI pThis = RT_FROM_MEMBER(pVirtio, VIRTIOSCSI, Virtio);
    1604     PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[qIdx];
    1605 
    1606     RTLogFlush(RTLogDefaultInstanceEx(RT_MAKE_U32(0, UINT16_MAX)));
     1664    PVIRTIOSCSIWORKER   pWorker   = &pThis->aWorkers[qIdx];
     1665    PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[qIdx];
     1666
     1667    RTLogFlush(RTLogDefaultInstanceEx(RT_MAKE_U32(0, UINT16_MAX))); /** @todo r=bird: Why? RTLogFlush(NULL) perhaps, and then inside \#ifdef LOG_ENABLED... */
    16071668
    16081669    if (qIdx == CONTROLQ_IDX || IS_REQ_QUEUE(qIdx))
     
    16101671        Log6Func(("%s has available data\n", QUEUENAME(qIdx)));
    16111672        /* Wake queue's worker thread up if sleeping */
    1612         if (!ASMAtomicXchgBool(&pWorker->fNotified, true))
     1673        if (!ASMAtomicXchgBool(&pWorkerR3->fNotified, true))
    16131674        {
    1614             if (ASMAtomicReadBool(&pWorker->fSleeping))
     1675            if (ASMAtomicReadBool(&pWorkerR3->fSleeping))
    16151676            {
    16161677                Log6Func(("waking %s worker.\n", QUEUENAME(qIdx)));
    1617                 int rc = SUPSemEventSignal(pThis->pSupDrvSession, pWorker->hEvtProcess);
     1678                int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pWorker->hEvtProcess);
    16181679                AssertRC(rc);
    16191680            }
     
    16241685        Log3Func(("Driver queued buffer(s) to %s\n", QUEUENAME(qIdx)));
    16251686        if (ASMAtomicXchgBool(&pThis->fEventsMissed, false))
    1626             virtioScsiR3ReportEventsMissed(pThis, 0);
     1687            virtioScsiR3ReportEventsMissed(pDevIns, pThis, 0);
    16271688    }
    16281689    else
     
    16331694 * @callback_method_impl{FNVIRTIOSTATUSCHANGED}
    16341695 */
    1635 static DECLCALLBACK(void) virtioScsiR3StatusChanged(PVIRTIOSTATE pVirtio,  uint32_t fVirtioReady)
    1636 {
    1637     PVIRTIOSCSI pThis = RT_FROM_MEMBER(pVirtio, VIRTIOSCSI, Virtio);
     1696static DECLCALLBACK(void) virtioScsiR3StatusChanged(PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC, uint32_t fVirtioReady)
     1697{
     1698    PVIRTIOSCSI     pThis     = RT_FROM_MEMBER(pVirtio, VIRTIOSCSI, Virtio);
     1699    PVIRTIOSCSICC   pThisCC   = RT_FROM_MEMBER(pVirtioCC, VIRTIOSCSICC, Virtio);
    16381700
    16391701    pThis->fVirtioReady = fVirtioReady;
     
    16471709        pThis->fHasInOutBufs = fFeatures & VIRTIO_SCSI_F_INOUT;
    16481710        pThis->fHasLunChange = fFeatures & VIRTIO_SCSI_F_CHANGE;
    1649         pThis->fQuiescing    = false;
    16501711        pThis->fResetting    = false;
    1651 
    1652         for (int i = 0; i < VIRTIOSCSI_QUEUE_CNT; i++)
     1712        pThisCC->fQuiescing  = false;
     1713
     1714        for (unsigned i = 0; i < VIRTIOSCSI_QUEUE_CNT; i++)
    16531715            pThis->afQueueAttached[i] = true;
    16541716    }
     
    16561718    {
    16571719        LogFunc(("VirtIO is resetting\n"));
    1658         for (int i = 0; i < VIRTIOSCSI_QUEUE_CNT; i++)
     1720        for (unsigned i = 0; i < VIRTIOSCSI_QUEUE_CNT; i++)
    16591721            pThis->afQueueAttached[i] = false;
    16601722    }
     
    17201782static DECLCALLBACK(int) virtioScsiR3DeviceQueryStatusLed(PPDMILEDPORTS pInterface, unsigned iTarget, PPDMLED *ppLed)
    17211783{
    1722     PVIRTIOSCSI pThis = RT_FROM_MEMBER(pInterface, VIRTIOSCSI, ILeds);
     1784    PVIRTIOSCSICC pThisCC = RT_FROM_MEMBER(pInterface, VIRTIOSCSICC, ILeds);
     1785    PVIRTIOSCSI   pThis   = PDMDEVINS_2_DATA(pThisCC->pDevIns, PVIRTIOSCSI);
    17231786    if (iTarget < pThis->cTargets)
    17241787    {
    1725         *ppLed = &pThis->paTargetInstances[iTarget].led;
     1788        *ppLed = &pThisCC->paTargetInstances[iTarget].led;
    17261789        Assert((*ppLed)->u32Magic == PDMLED_MAGIC);
    17271790        return VINF_SUCCESS;
     
    17421805{
    17431806    PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaPort);
    1744     PPDMDEVINS pDevIns = pTarget->pVirtioScsi->CTX_SUFF(pDevIns);
     1807    PPDMDEVINS        pDevIns = pTarget->pDevIns;
    17451808
    17461809    AssertPtrReturn(ppcszController, VERR_INVALID_POINTER);
     
    18871950static DECLCALLBACK(void *) virtioScsiR3DeviceQueryInterface(PPDMIBASE pInterface, const char *pszIID)
    18881951{
    1889     PVIRTIOSCSI pThis = RT_FROM_MEMBER(pInterface, VIRTIOSCSI, IBase);
    1890 
    1891     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE,         &pThis->IBase);
    1892     PDMIBASE_RETURN_INTERFACE(pszIID, PDMILEDPORTS,     &pThis->ILeds);
     1952    PVIRTIOSCSICC pThisCC = RT_FROM_MEMBER(pInterface, VIRTIOSCSICC, IBase);
     1953
     1954    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE,         &pThisCC->IBase);
     1955    PDMIBASE_RETURN_INTERFACE(pszIID, PDMILEDPORTS,     &pThisCC->ILeds);
    18931956
    18941957    return NULL;
     
    19271990static DECLCALLBACK(int) virtioScsiR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
    19281991{
    1929     PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     1992    PVIRTIOSCSI     pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     1993    PVIRTIOSCSICC   pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
    19301994    LogFunc(("LOAD EXEC!!\n"));
    19311995
     
    19532017    SSMR3GetU32(pSSM, &pThis->fHasLunChange);
    19542018    SSMR3GetU32(pSSM, &pThis->fResetting);
    1955     int rc = SSMR3GetU32(pSSM, &pThis->fQuiescing);
     2019    int rc = SSMR3GetU32(pSSM, &pThisCC->fQuiescing);
    19562020    AssertRCReturn(rc, rc);
    19572021
     
    19672031static DECLCALLBACK(int) virtioScsiR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
    19682032{
    1969     PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     2033    PVIRTIOSCSI     pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     2034    PVIRTIOSCSICC   pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
    19702035    LogFunc(("SAVE EXEC!!\n"));
    19712036
     
    19922057    SSMR3PutU32(pSSM, pThis->fHasLunChange);
    19932058    SSMR3PutU32(pSSM, pThis->fResetting);
    1994     SSMR3PutU32(pSSM, pThis->fQuiescing); /** @todo r=bird: This shall always be false, as the VM is suspended when saving, so no need to save this */
     2059    SSMR3PutU32(pSSM, pThisCC->fQuiescing); /** @todo r=bird: This shall always be false, as the VM is suspended when saving, so no need to save this */
    19952060
    19962061    /*
     
    20132078static DECLCALLBACK(void) virtioScsiR3Detach(PPDMDEVINS pDevIns, unsigned iTarget, uint32_t fFlags)
    20142079{
    2015     PVIRTIOSCSI       pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
    2016     PVIRTIOSCSITARGET pTarget = &pThis->paTargetInstances[iTarget];
     2080    PVIRTIOSCSI       pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     2081    PVIRTIOSCSICC     pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
     2082    AssertReturnVoid(iTarget < pThis->cTargets);
     2083    PVIRTIOSCSITARGET pTarget = &pThisCC->paTargetInstances[iTarget];
    20172084
    20182085    LogFunc((""));
     
    20232090
    20242091    /*
    2025      * Zero some important members.
     2092     * Zero all important members.
    20262093     */
    2027     pTarget->fPresent    = false;
    2028     pTarget->pDrvBase    = NULL;
     2094    pTarget->fPresent       = false;
     2095    pTarget->pDrvBase       = NULL;
     2096    pTarget->pDrvMedia      = NULL;
     2097    pTarget->pDrvMediaEx    = NULL;
     2098    pTarget->pMediaNotify   = NULL;
    20292099}
    20302100
     
    20372107{
    20382108    PVIRTIOSCSI       pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
    2039     PVIRTIOSCSITARGET pTarget = &pThis->paTargetInstances[iTarget];
    2040     int rc;
    2041 
    2042     pThis->pDevInsR3    = pDevIns;
    2043     pThis->pDevInsR0    = PDMDEVINS_2_R0PTR(pDevIns);
    2044     pThis->pDevInsRC    = PDMDEVINS_2_RCPTR(pDevIns);
    2045 
     2109    PVIRTIOSCSICC     pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
     2110    AssertReturn(iTarget < pThis->cTargets, VERR_PDM_LUN_NOT_FOUND);
     2111    PVIRTIOSCSITARGET pTarget = &pThisCC->paTargetInstances[iTarget];
     2112
     2113    Assert(pTarget->pDevIns == pDevIns);
    20462114    AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,
    20472115                    ("virtio-scsi: Device does not support hotplugging\n"),
     
    20562124     * required as well as optional.
    20572125     */
    2058     rc = PDMDevHlpDriverAttach(pDevIns, pTarget->iTarget, &pDevIns->IBase,
    2059                                &pTarget->pDrvBase, (const char *)&pTarget->pszTargetName);
     2126    int rc = PDMDevHlpDriverAttach(pDevIns, pTarget->iTarget, &pDevIns->IBase, &pTarget->pDrvBase, pTarget->pszTargetName);
    20602127    if (RT_SUCCESS(rc))
     2128    {
    20612129        pTarget->fPresent = true;
     2130        /** @todo r=bird: Shouldn't you resolve pDrvMedia, pDrvMediaEx and
     2131         *        pMediaNotify here?!? */
     2132    }
    20622133    else
    20632134        AssertMsgFailed(("Failed to attach %s. rc=%Rrc\n", pTarget->pszTargetName, rc));
     
    20652136    if (RT_FAILURE(rc))
    20662137    {
    2067         pTarget->fPresent = false;
    2068         pTarget->pDrvBase = NULL;
     2138        pTarget->fPresent      = false;
     2139        pTarget->pDrvBase       = NULL;
     2140        pTarget->pDrvMedia      = NULL;
     2141        pTarget->pDrvMediaEx    = NULL;
     2142        pTarget->pMediaNotify   = NULL;
    20692143    }
    20702144    return rc;
     
    20762150static DECLCALLBACK(bool) virtioScsiR3DeviceQuiesced(PPDMDEVINS pDevIns)
    20772151{
    2078     PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
    2079     LogFunc(("Device I/O activity quiesced: enmQuiescingFor=%d\n", pThis->enmQuiescingFor));
    2080 
    2081     if (pThis->enmQuiescingFor == kvirtIoScsiQuiescingForReset)
    2082         virtioR3PropagateResetNotification(&pThis->Virtio);
     2152    PVIRTIOSCSI     pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     2153    PVIRTIOSCSICC   pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
     2154    LogFunc(("Device I/O activity quiesced: enmQuiescingFor=%d\n", pThisCC->enmQuiescingFor));
     2155
     2156    if (pThisCC->enmQuiescingFor == kvirtIoScsiQuiescingForReset)
     2157        virtioR3PropagateResetNotification(pDevIns, &pThis->Virtio);
    20832158    /** @todo r=bird: Do we need other notifications here for suspend and/or poweroff? */
    20842159
    2085     pThis->enmQuiescingFor = kvirtIoScsiQuiescingForInvalid;
    2086     pThis->fQuiescing = false;
     2160    pThisCC->enmQuiescingFor = kvirtIoScsiQuiescingForInvalid;
     2161    pThisCC->fQuiescing = false;
    20872162    return true;
    20882163}
     
    20932168static void virtioScsiR3QuiesceDevice(PPDMDEVINS pDevIns, VIRTIOSCSIQUIESCINGFOR enmQuiscingFor)
    20942169{
    2095     PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     2170    PVIRTIOSCSI     pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     2171    PVIRTIOSCSICC   pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
    20962172
    20972173    /* Prevent worker threads from removing/processing elements from virtq's */
    2098     pThis->fQuiescing = true;
    2099     pThis->enmQuiescingFor = enmQuiscingFor;
     2174    pThisCC->fQuiescing = true;
     2175    pThisCC->enmQuiescingFor = enmQuiscingFor;
    21002176
    21012177    PDMDevHlpSetAsyncNotification(pDevIns, virtioScsiR3DeviceQuiesced);
     
    21112187static void virtioScsiR3SuspendOrPowerOff(PPDMDEVINS pDevIns, VIRTIOSCSIQUIESCINGFOR enmQuiscingFor)
    21122188{
    2113     PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     2189    PVIRTIOSCSI     pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     2190    PVIRTIOSCSICC   pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
    21142191
    21152192    virtioScsiR3QuiesceDevice(pDevIns, enmQuiscingFor);
     
    21242201    for (uint32_t i = 0; i < pThis->cTargets; i++)
    21252202    {
    2126         PVIRTIOSCSITARGET pTarget = &pThis->paTargetInstances[i];
    2127         if (pTarget->pDrvBase)
    2128             if (pTarget->pDrvMediaEx)
    2129                 pTarget->pDrvMediaEx->pfnNotifySuspend(pTarget->pDrvMediaEx);
     2203        PVIRTIOSCSITARGET pTarget = &pThisCC->paTargetInstances[i];
     2204        if (pTarget->pDrvMediaEx)
     2205            pTarget->pDrvMediaEx->pfnNotifySuspend(pTarget->pDrvMediaEx);
    21302206    }
    21312207}
     
    21542230static DECLCALLBACK(void) virtioScsiR3Resume(PPDMDEVINS pDevIns)
    21552231{
    2156     PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     2232    PVIRTIOSCSI     pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     2233    PVIRTIOSCSICC   pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
    21572234    LogFunc(("\n"));
    21582235
    2159     pThis->fQuiescing = false;
     2236    pThisCC->fQuiescing = false;
    21602237
    21612238    /* Wake worker threads flagged to skip pulling queue entries during quiesce
     
    21652242    for (uint16_t qIdx = 0; qIdx < VIRTIOSCSI_REQ_QUEUE_CNT; qIdx++)
    21662243    {
    2167         PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[qIdx];
    2168 
    2169         if (ASMAtomicReadBool(&pWorker->fSleeping))
     2244        if (ASMAtomicReadBool(&pThisCC->aWorkers[qIdx].fSleeping))
    21702245        {
    21712246            Log6Func(("waking %s worker.\n", QUEUENAME(qIdx)));
    2172             int rc = SUPSemEventSignal(pThis->pSupDrvSession, pWorker->hEvtProcess);
     2247            int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->aWorkers[qIdx].hEvtProcess);
    21732248            AssertRC(rc);
    21742249        }
     
    21762251
    21772252    /* Ensure guest is working the queues too. */
    2178     virtioR3PropagateResumeNotification(&pThis->Virtio);
     2253    virtioR3PropagateResumeNotification(pDevIns, &pThis->Virtio);
    21792254}
    21802255
     
    21982273{
    21992274    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
    2200     PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
    2201 
    2202     RTMemFree(pThis->paTargetInstances);
    2203     pThis->paTargetInstances = NULL;
     2275    PVIRTIOSCSI   pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     2276    PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
     2277
     2278    RTMemFree(pThisCC->paTargetInstances);
     2279    pThisCC->paTargetInstances = NULL;
    22042280
    22052281    for (unsigned qIdx = 0; qIdx < VIRTIOSCSI_QUEUE_CNT; qIdx++)
     
    22082284        if (pWorker->hEvtProcess != NIL_SUPSEMEVENT)
    22092285        {
    2210             SUPSemEventClose(pThis->pSupDrvSession, pWorker->hEvtProcess);
     2286            PDMDevHlpSUPSemEventClose(pDevIns, pWorker->hEvtProcess);
    22112287            pWorker->hEvtProcess = NIL_SUPSEMEVENT;
    22122288        }
    22132289    }
    22142290
    2215     virtioR3Term(&pThis->Virtio, pDevIns);
     2291    virtioR3Term(pDevIns, &pThis->Virtio, &pThisCC->Virtio);
    22162292    return VINF_SUCCESS;
    22172293}
     
    22232299{
    22242300    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    2225     PVIRTIOSCSI   pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
    2226     PCPDMDEVHLPR3 pHlp  = pDevIns->pHlpR3;
     2301    PVIRTIOSCSI   pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     2302    PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
     2303    PCPDMDEVHLPR3 pHlp    = pDevIns->pHlpR3;
    22272304
    22282305    /*
    22292306     * Quick initialization of the state data, making sure that the destructor always works.
    22302307     */
    2231     pThis->pDevInsR3 = pDevIns;
    2232     pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
    2233     pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
    2234     pThis->pSupDrvSession = PDMDevHlpGetSupDrvSession(pDevIns);
     2308    pThisCC->pDevIns = pDevIns;
    22352309
    22362310    LogFunc(("PDM device instance: %d\n", iInstance));
    22372311    RTStrPrintf(pThis->szInstance, sizeof(pThis->szInstance), "VIRTIOSCSI%d", iInstance);
    22382312
    2239     pThis->IBase.pfnQueryInterface = virtioScsiR3DeviceQueryInterface;
     2313    pThisCC->IBase.pfnQueryInterface = virtioScsiR3DeviceQueryInterface;
     2314    pThisCC->ILeds.pfnQueryStatusLed = virtioScsiR3DeviceQueryStatusLed;
    22402315
    22412316    /*
     
    22772352
    22782353    /* Initialize the generic Virtio core: */
    2279     pThis->Virtio.Callbacks.pfnStatusChanged  = virtioScsiR3StatusChanged;
    2280     pThis->Virtio.Callbacks.pfnQueueNotified  = virtioScsiR3Notified;
    2281     pThis->Virtio.Callbacks.pfnDevCapRead     = virtioScsiR3DevCapRead;
    2282     pThis->Virtio.Callbacks.pfnDevCapWrite    = virtioScsiR3DevCapWrite;
     2354    pThisCC->Virtio.Callbacks.pfnStatusChanged  = virtioScsiR3StatusChanged;
     2355    pThisCC->Virtio.Callbacks.pfnQueueNotified  = virtioScsiR3Notified;
     2356    pThisCC->Virtio.Callbacks.pfnDevCapRead     = virtioScsiR3DevCapRead;
     2357    pThisCC->Virtio.Callbacks.pfnDevCapWrite    = virtioScsiR3DevCapWrite;
    22832358
    22842359    VIRTIOPCIPARAMS VirtioPciParams;
     
    22932368    VirtioPciParams.uInterruptPin       = 0x01;
    22942369
    2295     rc = virtioR3Init(&pThis->Virtio, pDevIns, &VirtioPciParams, pThis->szInstance, VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED,
     2370    rc = virtioR3Init(pDevIns, &pThis->Virtio, &pThisCC->Virtio, &VirtioPciParams, pThis->szInstance,
     2371                      VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED,
    22962372                      &pThis->virtioScsiConfig /*pvDevSpecificCap*/, sizeof(pThis->virtioScsiConfig));
    22972373
     
    23182394        if (qIdx == CONTROLQ_IDX || IS_REQ_QUEUE(qIdx))
    23192395        {
    2320             rc = PDMDevHlpThreadCreate(pDevIns, &pThis->aWorkers[qIdx].pThread,
     2396            rc = PDMDevHlpThreadCreate(pDevIns, &pThisCC->aWorkers[qIdx].pThread,
    23212397                                       (void *)(uintptr_t)qIdx, virtioScsiR3WorkerThread,
    23222398                                       virtioScsiR3WorkerWakeUp, 0, RTTHREADTYPE_IO, QUEUENAME(qIdx));
     
    23272403            }
    23282404
    2329             rc = SUPSemEventCreate(pThis->pSupDrvSession, &pThis->aWorkers[qIdx].hEvtProcess);
     2405            rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pThis->aWorkers[qIdx].hEvtProcess);
    23302406            if (RT_FAILURE(rc))
    23312407                return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
     
    23402416    Log2Func(("Probing %d targets ...\n", pThis->cTargets));
    23412417
    2342     pThis->paTargetInstances = (PVIRTIOSCSITARGET)RTMemAllocZ(sizeof(VIRTIOSCSITARGET) * pThis->cTargets);
    2343     if (!pThis->paTargetInstances)
     2418    pThisCC->paTargetInstances = (PVIRTIOSCSITARGET)RTMemAllocZ(sizeof(VIRTIOSCSITARGET) * pThis->cTargets);
     2419    if (!pThisCC->paTargetInstances)
    23442420        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to allocate memory for target states"));
    23452421
    2346     for (RTUINT iTarget = 0; iTarget < pThis->cTargets; iTarget++)
    2347     {
    2348         PVIRTIOSCSITARGET pTarget = &pThis->paTargetInstances[iTarget];
     2422    for (uint32_t iTarget = 0; iTarget < pThis->cTargets; iTarget++)
     2423    {
     2424        PVIRTIOSCSITARGET pTarget = &pThisCC->paTargetInstances[iTarget];
    23492425
    23502426        if (RTStrAPrintf(&pTarget->pszTargetName, "VSCSI%u", iTarget) < 0)
     
    23522428
    23532429        /* Initialize static parts of the device. */
     2430        pTarget->pDevIns = pDevIns;
    23542431        pTarget->iTarget = iTarget;
    2355         pTarget->pVirtioScsi = pThis;
    23562432        pTarget->led.u32Magic = PDMLED_MAGIC;
    23572433
     
    23722448        pTarget->IBase.pfnQueryInterface                 = virtioScsiR3TargetQueryInterface;
    23732449        pTarget->ILed.pfnQueryStatusLed                  = virtioScsiR3TargetQueryStatusLed;
    2374         pThis->ILeds.pfnQueryStatusLed                   = virtioScsiR3DeviceQueryStatusLed;
    23752450        pTarget->led.u32Magic                            = PDMLED_MAGIC;
    23762451
     
    24002475
    24012476            pTarget->pMediaNotify = PDMIBASE_QUERY_INTERFACE(pTarget->pDrvBase, PDMIMEDIANOTIFY);
    2402             AssertMsgReturn(VALID_PTR(pTarget->pDrvMediaEx),
     2477            AssertMsgReturn(VALID_PTR(pTarget->pMediaNotify),
    24032478                            ("virtio-scsi configuration error: LUN#%u: Failed to get set Media notify obj!\n", iTarget),
    24042479                            VERR_PDM_MISSING_INTERFACE);
     
    24242499    PPDMIBASE pUpBase;
    24252500    AssertCompile(PDM_STATUS_LUN >= VIRTIOSCSI_MAX_TARGETS);
    2426     rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pThis->IBase, &pUpBase, "Status Port");
     2501    rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pThisCC->IBase, &pUpBase, "Status Port");
    24272502    if (RT_FAILURE(rc) && rc != VERR_PDM_NO_ATTACHED_DRIVER)
    24282503        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to attach the status LUN"));
  • trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp

    r81662 r81675  
    121121*   Internal Functions                                                                                                           *
    122122*********************************************************************************************************************************/
    123 static void virtioNotifyGuestDriver(PVIRTIOSTATE pVirtio, uint16_t idxQueue, bool fForce);
    124 static int  virtioKick(PVIRTIOSTATE pVirtio, uint8_t uCause, uint16_t uVec, bool fForce);
     123static void virtioNotifyGuestDriver(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, bool fForce);
     124static int  virtioKick(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint8_t uCause, uint16_t uVec, bool fForce);
    125125
    126126/** @name Internal queue operations
     
    137137 * Accessor for virtq descriptor
    138138 */
    139 DECLINLINE(void) virtioReadDesc(PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint32_t uDescIdx, PVIRTQ_DESC_T pDesc)
     139DECLINLINE(void) virtioReadDesc(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue,
     140                                uint32_t idxDesc, PVIRTQ_DESC_T pDesc)
    140141{
    141142    //Log(("%s virtioQueueReadDesc: ring=%p idx=%u\n", INSTANCE(pState), pVirtQ, idx));
    142143    AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n"));
    143     PDMDevHlpPhysRead(pVirtio->CTX_SUFF(pDevIns),
    144                       pVirtio->aGCPhysQueueDesc[idxQueue] + sizeof(VIRTQ_DESC_T) * (uDescIdx % pVirtio->uQueueSize[idxQueue]),
     144    uint16_t const cQueueItems = RT_MAX(pVirtio->uQueueSize[idxQueue], 1); /* Make sure to avoid div-by-zero. */
     145    PDMDevHlpPhysRead(pDevIns, /** @todo r=bird: PDMDevHlpPhysRead or PDMDevHlpPCIPhysRead ?!? (ditto rest of file + writes) */
     146                      pVirtio->aGCPhysQueueDesc[idxQueue] + sizeof(VIRTQ_DESC_T) * (idxDesc % cQueueItems),
    145147                      pDesc, sizeof(VIRTQ_DESC_T));
    146148}
     
    149151 * Accessors for virtq avail ring
    150152 */
    151 DECLINLINE(uint16_t) virtioReadAvailDescIdx(PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint32_t availIdx)
     153DECLINLINE(uint16_t) virtioReadAvailDescIdx(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint32_t availIdx)
    152154{
    153155    uint16_t uDescIdx;
    154156    AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n"));
    155     PDMDevHlpPhysRead(pVirtio->CTX_SUFF(pDevIns),
     157    uint16_t const cQueueItems = RT_MAX(pVirtio->uQueueSize[idxQueue], 1); /* Make sure to avoid div-by-zero. */
     158    PDMDevHlpPhysRead(pDevIns,
    156159                        pVirtio->aGCPhysQueueAvail[idxQueue]
    157                       + RT_UOFFSETOF_DYN(VIRTQ_AVAIL_T, auRing[availIdx % pVirtio->uQueueSize[idxQueue]]),
     160                      + RT_UOFFSETOF_DYN(VIRTQ_AVAIL_T, auRing[availIdx % cQueueItems]),
    158161                      &uDescIdx, sizeof(uDescIdx));
    159162    return uDescIdx;
    160163}
    161164
    162 DECLINLINE(uint16_t) virtioReadAvailRingIdx(PVIRTIOSTATE pVirtio, uint16_t idxQueue)
     165DECLINLINE(uint16_t) virtioReadAvailRingIdx(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue)
    163166{
    164167    uint16_t uIdx = 0;
    165168    AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n"));
    166     PDMDevHlpPhysRead(pVirtio->CTX_SUFF(pDevIns),
     169    PDMDevHlpPhysRead(pDevIns,
    167170                      pVirtio->aGCPhysQueueAvail[idxQueue] + RT_UOFFSETOF(VIRTQ_AVAIL_T, uIdx),
    168171                      &uIdx, sizeof(uIdx));
     
    170173}
    171174
    172 DECLINLINE(bool) virtqIsEmpty(PVIRTIOSTATE pVirtio, uint16_t idxQueue)
    173 {
    174     return virtioReadAvailRingIdx(pVirtio, idxQueue) == pVirtio->virtqState[idxQueue].uAvailIdx;
     175DECLINLINE(bool) virtqIsEmpty(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue)
     176{
     177    return virtioReadAvailRingIdx(pDevIns, pVirtio, idxQueue) == pVirtio->virtqState[idxQueue].uAvailIdx;
    175178}
    176179
    177180#if 0 /* unused */
    178 DECLINLINE(uint16_t) virtioReadAvailFlags(PVIRTIOSTATE pVirtio, uint16_t idxQueue)
     181DECLINLINE(uint16_t) virtioReadAvailFlags(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue)
    179182{
    180183    uint16_t fFlags;
    181184    AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n"));
    182     PDMDevHlpPhysRead(pVirtio->CTX_SUFF(pDevIns),
     185    PDMDevHlpPhysRead(pDevIns,
    183186                      pVirtio->aGCPhysQueueAvail[idxQueue] + RT_UOFFSETOF(VIRTQ_AVAIL_T, fFlags),
    184187                      &fFlags, sizeof(fFlags));
     
    187190#endif
    188191
    189 DECLINLINE(uint16_t) virtioReadAvailUsedEvent(PVIRTIOSTATE pVirtio, uint16_t idxQueue)
     192DECLINLINE(uint16_t) virtioReadAvailUsedEvent(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue)
    190193{
    191194    uint16_t uUsedEventIdx;
    192     /** VirtIO 1.0 uUsedEventIdx (used_event) immediately follows ring */
     195    /* VirtIO 1.0 uUsedEventIdx (used_event) immediately follows ring */
    193196    AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n"));
    194     PDMDevHlpPhysRead(pVirtio->CTX_SUFF(pDevIns),
     197    PDMDevHlpPhysRead(pDevIns,
    195198                      pVirtio->aGCPhysQueueAvail[idxQueue] + RT_UOFFSETOF_DYN(VIRTQ_AVAIL_T, auRing[pVirtio->uQueueSize[idxQueue]]),
    196199                      &uUsedEventIdx, sizeof(uUsedEventIdx));
     
    202205 * @{
    203206 */
    204 DECLINLINE(void) virtioWriteUsedElem(PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint32_t usedIdx, uint32_t uDescIdx, uint32_t uLen)
     207DECLINLINE(void) virtioWriteUsedElem(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue,
     208                                     uint32_t usedIdx, uint32_t uDescIdx, uint32_t uLen)
    205209{
    206210    VIRTQ_USED_ELEM_T elem = { uDescIdx,  uLen };
    207211    AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n"));
    208     PDMDevHlpPCIPhysWrite(pVirtio->CTX_SUFF(pDevIns),
    209                             pVirtio->aGCPhysQueueUsed[idxQueue]
    210                           + RT_UOFFSETOF_DYN(VIRTQ_USED_T, aRing[usedIdx % pVirtio->uQueueSize[idxQueue]]),
     212    uint16_t const cQueueItems = RT_MAX(pVirtio->uQueueSize[idxQueue], 1); /* Make sure to avoid div-by-zero. */
     213    PDMDevHlpPCIPhysWrite(pDevIns,
     214                          pVirtio->aGCPhysQueueUsed[idxQueue] + RT_UOFFSETOF_DYN(VIRTQ_USED_T, aRing[usedIdx % cQueueItems]),
    211215                          &elem, sizeof(elem));
    212216}
    213217
    214 DECLINLINE(void) virtioWriteUsedRingIdx(PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint16_t uIdx)
     218DECLINLINE(void) virtioWriteUsedRingIdx(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint16_t uIdx)
    215219{
    216220    AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n"));
    217     PDMDevHlpPCIPhysWrite(pVirtio->CTX_SUFF(pDevIns),
     221    PDMDevHlpPCIPhysWrite(pDevIns,
    218222                          pVirtio->aGCPhysQueueUsed[idxQueue] + RT_UOFFSETOF(VIRTQ_USED_T, uIdx),
    219223                          &uIdx, sizeof(uIdx));
     
    221225
    222226#ifdef LOG_ENABLED
    223 DECLINLINE(uint16_t) virtioReadUsedRingIdx(PVIRTIOSTATE pVirtio, uint16_t idxQueue)
    224 {
    225     uint16_t uIdx;
     227DECLINLINE(uint16_t) virtioReadUsedRingIdx(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue)
     228{
     229    uint16_t uIdx = 0;
    226230    AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n"));
    227     PDMDevHlpPhysRead(pVirtio->CTX_SUFF(pDevIns),
     231    PDMDevHlpPhysRead(pDevIns,
    228232                      pVirtio->aGCPhysQueueUsed[idxQueue] + RT_UOFFSETOF(VIRTQ_USED_T, uIdx),
    229233                      &uIdx, sizeof(uIdx));
     
    232236#endif
    233237
    234 DECLINLINE(uint16_t) virtioReadUsedFlags(PVIRTIOSTATE pVirtio, uint16_t idxQueue)
    235 {
    236     uint16_t fFlags;
     238DECLINLINE(uint16_t) virtioReadUsedFlags(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue)
     239{
     240    uint16_t fFlags = 0;
    237241    AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n"));
    238     PDMDevHlpPhysRead(pVirtio->CTX_SUFF(pDevIns),
     242    PDMDevHlpPhysRead(pDevIns,
    239243                      pVirtio->aGCPhysQueueUsed[idxQueue] + RT_UOFFSETOF(VIRTQ_USED_T, fFlags),
    240244                      &fFlags, sizeof(fFlags));
     
    243247
    244248#if 0 /* unused */
    245 DECLINLINE(void) virtioWriteUsedFlags(PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint32_t fFlags)
     249DECLINLINE(void) virtioWriteUsedFlags(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint32_t fFlags)
    246250{
    247251    AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n"));
    248252    RT_UNTRUSTED_VALIDATED_FENCE(); /* VirtIO 1.0, Section 3.2.1.4.1 */
    249     PDMDevHlpPCIPhysWrite(pVirtio->CTX_SUFF(pDevIns),
     253    PDMDevHlpPCIPhysWrite(pDevIns,
    250254                          pVirtio->aGCPhysQueueUsed[idxQueue] + RT_UOFFSETOF(VIRTQ_USED_T, fFlags),
    251255                          &fFlags, sizeof(fFlags));
     
    254258
    255259#if 0 /* unused */
    256 DECLINLINE(uint16_t) virtioReadUsedAvailEvent(PVIRTIOSTATE pVirtio, uint16_t idxQueue)
     260DECLINLINE(uint16_t) virtioReadUsedAvailEvent(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue)
    257261{
    258262    uint16_t uAvailEventIdx;
     
    260264    /** VirtIO 1.0 uAvailEventIdx (avail_event) immediately follows ring */
    261265    AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n"));
    262     PDMDevHlpPhysRead(pVirtio->CTX_SUFF(pDevIns),
     266    PDMDevHlpPhysRead(pDevIns,
    263267                      pVirtio->aGCPhysQueueUsed[idxQueue] + RT_UOFFSETOF_DYN(VIRTQ_USED_T, aRing[pVirtio->uQueueSize[idxQueue]]),
    264268                      &uAvailEventIdx, sizeof(uAvailEventIdx));
     
    268272
    269273#if 0 /* unused */
    270 DECLINLINE(void) virtioWriteUsedAvailEvent(PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint32_t uAvailEventIdx)
     274DECLINLINE(void) virtioWriteUsedAvailEvent(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint32_t uAvailEventIdx)
    271275{
    272276    /** VirtIO 1.0 uAvailEventIdx (avail_event) immediately follows ring */
    273277    AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n"));
    274     PDMDevHlpPCIPhysWrite(pVirtio->CTX_SUFF(pDevIns),
     278    PDMDevHlpPCIPhysWrite(pDevIns,
    275279                          pVirtio->aGCPhysQueueUsed[idxQueue] + RT_UOFFSETOF_DYN(VIRTQ_USED_T, aRing[pVirtio->uQueueSize[idxQueue]]),
    276280                          &uAvailEventIdx, sizeof(uAvailEventIdx));
     
    411415 * Allocate client context for client to work with VirtIO-provided with queue
    412416 *
    413  * @param   pVirtio     Pointer to the virtio state.
     417 * @param   pVirtio     Pointer to the shared virtio state.
    414418 * @param   idxQueue    Queue number
    415419 * @param   pcszName    Name to give queue
     
    454458 * Check if the associated queue is empty
    455459 *
    456  * @param hVirtio       Handle for VirtIO framework
    457  * @param idxQueue          Queue number
     460 * @param   pDevIns     The device instance (for reading).
     461 * @param   pVirtio     Pointer to the shared virtio state.
     462 * @param   idxQueue    Queue number
    458463 *
    459464 * @retval true  Queue is empty or unavailable.
    460465 * @retval false Queue is available and has entries
    461466 */
    462 bool virtioQueueIsEmpty(PVIRTIOSTATE pVirtio, uint16_t idxQueue)
     467bool virtioQueueIsEmpty(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue)
    463468{
    464469    if (pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK)
    465         return virtqIsEmpty(pVirtio, idxQueue);
     470        return virtqIsEmpty(pDevIns, pVirtio, idxQueue);
    466471    return true;
    467472}
     
    478483 * at some point to return the data to the guest and complete the transaction.
    479484 *
    480  * @param   pVirtio     Pointer to the virtio state.
     485 * @param   pDevIns     The device instance.
     486 * @param   pVirtio     Pointer to the shared virtio state.
    481487 * @param   idxQueue    Queue number
    482488 * @param   fRemove     flags whether to remove desc chain from queue (false = peek)
     
    489495 * @retval  VERR_NOT_AVAILABLE   If the queue is empty.
    490496 */
    491 int virtioR3QueueGet(PVIRTIOSTATE pVirtio, uint16_t idxQueue, PPVIRTIO_DESC_CHAIN_T ppDescChain,  bool fRemove)
     497int virtioR3QueueGet(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue,
     498                     PPVIRTIO_DESC_CHAIN_T ppDescChain, bool fRemove)
    492499{
    493500    AssertReturn(ppDescChain, VERR_INVALID_PARAMETER);
     
    505512                    ("Guest driver not in ready state.\n"), VERR_INVALID_STATE);
    506513
    507     if (virtqIsEmpty(pVirtio, idxQueue))
     514    if (virtqIsEmpty(pDevIns, pVirtio, idxQueue))
    508515        return VERR_NOT_AVAILABLE;
    509516
    510     uint16_t uHeadIdx = virtioReadAvailDescIdx(pVirtio, idxQueue, pVirtq->uAvailIdx);
     517    uint16_t uHeadIdx = virtioReadAvailDescIdx(pDevIns, pVirtio, idxQueue, pVirtq->uAvailIdx);
    511518    uint16_t uDescIdx = uHeadIdx;
    512519
     
    545552        RT_UNTRUSTED_VALIDATED_FENCE();
    546553
    547         virtioReadDesc(pVirtio, idxQueue, uDescIdx, &desc);
     554        virtioReadDesc(pDevIns, pVirtio, idxQueue, uDescIdx, &desc);
    548555
    549556        if (desc.fFlags & VIRTQ_DESC_F_WRITE)
     
    604611 *
    605612 *
    606  * @param   pVirtio         Pointer to the virtio state.
     613 * @param   pDevIns         The device instance (for reading).
     614 * @param   pVirtio         Pointer to the shared virtio state.
    607615 * @param   idxQueue        Queue number
    608616 *
     
    621629 * @retval  VERR_NOT_AVAILABLE Queue is empty
    622630 */
    623 int virtioR3QueuePut(PVIRTIOSTATE pVirtio, uint16_t idxQueue, PRTSGBUF pSgVirtReturn,
     631int virtioR3QueuePut(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, PRTSGBUF pSgVirtReturn,
    624632                     PVIRTIO_DESC_CHAIN_T pDescChain, bool fFence)
    625633{
     
    632640
    633641    Log3Func(("Copying client data to %s, desc chain (head desc_idx %d)\n",
    634               QUEUENAME(pVirtio, idxQueue), virtioReadUsedRingIdx(pVirtio, idxQueue)));
     642              QUEUENAME(pVirtio, idxQueue), virtioReadUsedRingIdx(pDevIns, pVirtio, idxQueue)));
    635643
    636644    /*
     
    650658        uint64_t dstSgCur   = (uint64_t)pSgPhysReturn->pvSegCur;
    651659        cbCopy = RT_MIN((uint64_t)pSgVirtReturn->cbSegLeft, dstSgLen - (dstSgCur - dstSgStart));
    652         PDMDevHlpPhysWrite(pVirtio->CTX_SUFF(pDevIns),
    653                            (RTGCPHYS)pSgPhysReturn->pvSegCur, pSgVirtReturn->pvSegCur, cbCopy);
     660        PDMDevHlpPhysWrite(pDevIns, (RTGCPHYS)pSgPhysReturn->pvSegCur, pSgVirtReturn->pvSegCur, cbCopy);
    654661        RTSgBufAdvance(pSgVirtReturn, cbCopy);
    655662        RTSgBufAdvance(pSgPhysReturn, cbCopy);
     
    660667        RT_UNTRUSTED_NONVOLATILE_COPY_FENCE(); /* needed? */
    661668
    662     /** If this write-ahead crosses threshold where the driver wants to get an event flag it */
     669    /* If this write-ahead crosses threshold where the driver wants to get an event flag it */
    663670    if (pVirtio->uDriverFeatures & VIRTIO_F_EVENT_IDX)
    664         if (pVirtq->uUsedIdx == virtioReadAvailUsedEvent(pVirtio, idxQueue))
     671        if (pVirtq->uUsedIdx == virtioReadAvailUsedEvent(pDevIns, pVirtio, idxQueue))
    665672            pVirtq->fEventThresholdReached = true;
    666673
    667     Assert(!(cbCopy & UINT64_C(0xffffffff00000000)));
     674    Assert(!(cbCopy >> 32));
    668675
    669676    /*
    670677     * Place used buffer's descriptor in used ring but don't update used ring's slot index.
    671678     * That will be done with a subsequent client call to virtioQueueSync() */
    672     virtioWriteUsedElem(pVirtio, idxQueue, pVirtq->uUsedIdx++, pDescChain->uHeadIdx, (uint32_t)(cbCopy & UINT32_C(0xffffffff)));
    673 
    674     Log2Func((".... Copied %lu bytes to %lu byte buffer, residual=%lu\n",
     679    virtioWriteUsedElem(pDevIns, pVirtio, idxQueue, pVirtq->uUsedIdx++, pDescChain->uHeadIdx, (uint32_t)cbCopy);
     680
     681    Log2Func((".... Copied %zu bytes to %u byte buffer, residual=%zu\n",
    675682              cbCopy, pDescChain->cbPhysReturn, pDescChain->cbPhysReturn - cbCopy));
    676683
    677     Log6Func(("Write ahead used_idx=%d, %s used_idx=%d\n",
    678               pVirtq->uUsedIdx, QUEUENAME(pVirtio, idxQueue), virtioReadUsedRingIdx(pVirtio, idxQueue)));
     684    Log6Func(("Write ahead used_idx=%u, %s used_idx=%u\n",
     685              pVirtq->uUsedIdx, QUEUENAME(pVirtio, idxQueue), virtioReadUsedRingIdx(pDevIns, pVirtio, idxQueue)));
    679686
    680687    RTMemFree((void *)pDescChain->pSgPhysSend->paSegs);
     
    699706 * specification, Section 2.4 "Virtqueues").
    700707 *
    701  * @param   pVirtio     Pointer to the virtio state.
     708 * @param   pDevIns     The device instance.
     709 * @param   pVirtio     Pointer to the shared virtio state.
    702710 * @param   idxQueue    Queue number
    703711 *
     
    706714 * @retval  VERR_INVALID_STATE VirtIO not in ready state
    707715 */
    708 int virtioQueueSync(PVIRTIOSTATE pVirtio, uint16_t idxQueue)
     716int virtioQueueSync(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue)
    709717{
    710718    Assert(idxQueue < RT_ELEMENTS(pVirtio->virtqState));
     
    715723
    716724    Log6Func(("Updating %s used_idx from %u to %u\n",
    717               QUEUENAME(pVirtio, idxQueue), virtioReadUsedRingIdx(pVirtio, idxQueue), pVirtq->uUsedIdx));
    718 
    719     virtioWriteUsedRingIdx(pVirtio, idxQueue, pVirtq->uUsedIdx);
    720     virtioNotifyGuestDriver(pVirtio, idxQueue, false);
     725              QUEUENAME(pVirtio, idxQueue), virtioReadUsedRingIdx(pDevIns, pVirtio, idxQueue), pVirtq->uUsedIdx));
     726
     727    virtioWriteUsedRingIdx(pDevIns, pVirtio, idxQueue, pVirtq->uUsedIdx);
     728    virtioNotifyGuestDriver(pDevIns, pVirtio, idxQueue, false);
    721729
    722730    return VINF_SUCCESS;
     
    726734/**
    727735 */
    728 static void virtior3QueueNotified(PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint16_t uNotifyIdx)
     736static void virtioR3QueueNotified(PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC, uint16_t idxQueue, uint16_t uNotifyIdx)
    729737{
    730738    /* See VirtIO 1.0, section 4.1.5.2 It implies that idxQueue and uNotifyIdx should match.
     
    742750
    743751    AssertReturnVoid(idxQueue < RT_ELEMENTS(pVirtio->virtqState));
    744     PVIRTQSTATE pVirtq = &pVirtio->virtqState[idxQueue];
    745     Log6Func(("%s\n", pVirtq->szVirtqName));
    746     RT_NOREF(pVirtq);
     752    Log6Func(("%s\n", pVirtio->virtqState[idxQueue].szVirtqName));
    747753
    748754    /* Inform client */
    749     pVirtio->Callbacks.pfnQueueNotified(pVirtio, idxQueue);
     755    pVirtioCC->Callbacks.pfnQueueNotified(pVirtio, pVirtioCC, idxQueue);
    750756}
    751757#endif /* IN_RING3 */
     
    758764 * See VirtIO 1.0 specification (section 2.4.7).
    759765 *
    760  * @param   pVirtio     Pointer to the virtio state.
     766 * @param   pDevIns     The device instance.
     767 * @param   pVirtio     Pointer to the shared virtio state.
    761768 * @param   idxQueue    Queue to check for guest interrupt handling preference
    762769 * @param   fForce      Overrides idxQueue, forcing notification regardless of driver's
     
    766773 *                      as they only cause the guest driver to [re]scan queues for work to do.
    767774 */
    768 static void virtioNotifyGuestDriver(PVIRTIOSTATE pVirtio, uint16_t idxQueue, bool fForce)
     775static void virtioNotifyGuestDriver(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, bool fForce)
    769776{
    770777    Assert(idxQueue < RT_ELEMENTS(pVirtio->virtqState));
     
    776783        if (pVirtq->fEventThresholdReached)
    777784        {
    778             virtioKick(pVirtio, VIRTIO_ISR_VIRTQ_INTERRUPT, pVirtio->uQueueMsixVector[idxQueue], fForce);
     785            virtioKick(pDevIns, pVirtio, VIRTIO_ISR_VIRTQ_INTERRUPT, pVirtio->uQueueMsixVector[idxQueue], fForce);
    779786            pVirtq->fEventThresholdReached = false;
    780787            return;
     
    785792    {
    786793        /** If guest driver hasn't suppressed interrupts, interrupt  */
    787         if (fForce || !(virtioReadUsedFlags(pVirtio, idxQueue) & VIRTQ_AVAIL_F_NO_INTERRUPT))
     794        if (fForce || !(virtioReadUsedFlags(pDevIns, pVirtio, idxQueue) & VIRTQ_AVAIL_F_NO_INTERRUPT))
    788795        {
    789             virtioKick(pVirtio, VIRTIO_ISR_VIRTQ_INTERRUPT, pVirtio->uQueueMsixVector[idxQueue], fForce);
     796            virtioKick(pDevIns, pVirtio, VIRTIO_ISR_VIRTQ_INTERRUPT, pVirtio->uQueueMsixVector[idxQueue], fForce);
    790797            return;
    791798        }
     
    797804 * Raise interrupt or MSI-X
    798805 *
    799  * @param   pVirtio         The device state structure.
    800  * @param   uCause          Interrupt cause bit mask to set in PCI ISR port.
    801  * @param   uVec            MSI-X vector, if enabled
    802  * @param   uForce          True of out-of-band
    803  */
    804 static int virtioKick(PVIRTIOSTATE pVirtio, uint8_t uCause, uint16_t uMsixVector, bool fForce)
     806 * @param   pDevIns     The device instance.
     807 * @param   pVirtio     Pointer to the shared virtio state.
     808 * @param   uCause      Interrupt cause bit mask to set in PCI ISR port.
     809 * @param   uVec        MSI-X vector, if enabled
     810 * @param   uForce      True of out-of-band
     811 */
     812static int virtioKick(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint8_t uCause, uint16_t uMsixVector, bool fForce)
    805813{
    806814   if (fForce)
     
    816824    {
    817825        pVirtio->uISR |= uCause;
    818         PDMDevHlpPCISetIrq(pVirtio->CTX_SUFF(pDevIns), 0, PDM_IRQ_LEVEL_HIGH);
     826        PDMDevHlpPCISetIrq(pDevIns, 0, PDM_IRQ_LEVEL_HIGH);
    819827    }
    820828    else if (uMsixVector != VIRTIO_MSI_NO_VECTOR)
    821829    {
    822830        Log6Func(("MSI-X enabled, calling PDMDevHlpPCISetIrq with vector: 0x%x\n", uMsixVector));
    823         PDMDevHlpPCISetIrq(pVirtio->CTX_SUFF(pDevIns), uMsixVector, 1);
     831        PDMDevHlpPCISetIrq(pDevIns, uMsixVector, 1);
    824832    }
    825833    return VINF_SUCCESS;
     
    829837 * Lower interrupt. (Called when guest reads ISR)
    830838 *
    831  * @param   pVirtio      The device state structure.
    832  */
    833 static void virtioLowerInterrupt(PVIRTIOSTATE pVirtio)
    834 {
    835     PDMDevHlpPCISetIrq(pVirtio->CTX_SUFF(pDevIns), 0, PDM_IRQ_LEVEL_LOW);
     839 * @param   pDevIns     The device instance.
     840 */
     841static void virtioLowerInterrupt(PPDMDEVINS pDevIns)
     842{
     843    PDMDevHlpPCISetIrq(pDevIns, 0, PDM_IRQ_LEVEL_LOW);
    836844}
    837845
     
    851859}
    852860
    853 static void virtioResetDevice(PVIRTIOSTATE pVirtio)
     861static void virtioResetDevice(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio)
    854862{
    855863    Log2Func(("\n"));
     
    860868    pVirtio->uISR                   = 0;
    861869
    862     virtioLowerInterrupt(pVirtio);
     870    virtioLowerInterrupt(pDevIns);
    863871
    864872    if (!pVirtio->fMsiSupport)  /* VirtIO 1.0, 4.1.4.3 and 4.1.5.1.2 */
     
    874882 * Enable or disable queue
    875883 *
    876  * @param   pVirtio     Pointer to the virtio state.
     884 * @param   pVirtio     Pointer to the shared virtio state.
    877885 * @param   idxQueue    Queue number
    878886 * @param   fEnabled    Flag indicating whether to enable queue or not
     
    909917 * The driver itself will not  until the device has read the status change.
    910918 */
    911 static void virtioGuestR3Resetted(PVIRTIOSTATE pVirtio)
     919static void virtioGuestR3WasReset(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC)
    912920{
    913921    LogFunc(("Guest reset the device\n"));
    914922
    915923    /* Let the client know */
    916     pVirtio->Callbacks.pfnStatusChanged(pVirtio, 0);
    917     virtioResetDevice(pVirtio);
     924    pVirtioCC->Callbacks.pfnStatusChanged(pVirtio, pVirtioCC, 0);
     925    virtioResetDevice(pDevIns, pVirtio);
    918926}
    919927#endif /* IN_RING3 */
     
    924932 * @returns VBox status code
    925933 *
    926  * @param   pVirtio     Virtio instance state
     934 * @param   pDevIns     The device instance.
     935 * @param   pVirtio     Pointer to the shared virtio state.
     936 * @param   pVirtioCC   Pointer to the current context virtio state.
    927937 * @param   fWrite      Set if write access, clear if read access.
    928938 * @param   offCfg      The common configuration capability offset.
     
    930940 * @param   pv          Pointer to location to write to or read from
    931941 */
    932 static int virtioCommonCfgAccessed(PVIRTIOSTATE pVirtio, int fWrite, off_t offCfg, unsigned cb, void *pv)
     942static int virtioCommonCfgAccessed(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC, int fWrite, off_t offCfg, unsigned cb, void *pv)
    933943{
    934944/**
     
    11001110        if (fWrite) /* Guest WRITE pCommonCfg->uDeviceStatus */
    11011111        {
    1102             pVirtio->uDeviceStatus = *(uint8_t *)pv;
    1103             Log6Func(("Guest wrote uDeviceStatus ................ ("));
    1104             virtioLogDeviceStatus(pVirtio->uDeviceStatus);
     1112            uint8_t const fNewStatus = *(uint8_t *)pv;
     1113            Log6Func(("Guest wrote uDeviceStatus (%#x, was %#x, change #%x) ................ (",
     1114                      fNewStatus, pVirtio->uDeviceStatus, fNewStatus ^ pVirtio->uDeviceStatus));
     1115            virtioLogDeviceStatus(fNewStatus);
    11051116            Log6((")\n"));
     1117
     1118            /* If the status changed or we were reset, we need to go to ring-3 as
     1119               it requires notifying the parent device. */
     1120            bool const fStatusChanged =    (fNewStatus & VIRTIO_STATUS_DRIVER_OK)
     1121                                        != (pVirtio->uPrevDeviceStatus & VIRTIO_STATUS_DRIVER_OK);
     1122#ifndef IN_RING3
     1123            if (fStatusChanged || fNewStatus == 0)
     1124            {
     1125                Log6Func(("=>ring3\n"));
     1126                return VINF_IOM_R3_MMIO_WRITE;
     1127            }
     1128#endif
     1129            pVirtio->uDeviceStatus = fNewStatus;
     1130
     1131#ifdef IN_RING3
     1132            /*
     1133             * Notify client only if status actually changed from last time and when we're reset.
     1134             */
    11061135            if (pVirtio->uDeviceStatus == 0)
    1107                 virtioGuestR3Resetted(pVirtio);
     1136                virtioGuestR3WasReset(pDevIns, pVirtio, pVirtioCC);
     1137            if (fStatusChanged)
     1138                pVirtioCC->Callbacks.pfnStatusChanged(pVirtio, pVirtioCC, fNewStatus & VIRTIO_STATUS_DRIVER_OK);
     1139#endif
    11081140            /*
    1109              * Notify client only if status actually changed from last time.
     1141             * Save the current status for the next write so we can see what changed.
    11101142             */
    1111             uint32_t const fOkayNow = pVirtio->uDeviceStatus     & VIRTIO_STATUS_DRIVER_OK;
    1112             uint32_t const fWasOkay = pVirtio->uPrevDeviceStatus & VIRTIO_STATUS_DRIVER_OK;
    1113             if (fOkayNow != fWasOkay)
    1114                 pVirtio->Callbacks.pfnStatusChanged(pVirtio, fOkayNow);
    11151143            pVirtio->uPrevDeviceStatus = pVirtio->uDeviceStatus;
    11161144        }
     
    11821210static DECLCALLBACK(VBOXSTRICTRC) virtioMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
    11831211{
    1184     PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE);
     1212    PVIRTIOSTATE   pVirtio   = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE);
     1213    PVIRTIOSTATECC pVirtioCC = PDMINS_2_DATA_CC(pDevIns, PVIRTIOSTATECC);
    11851214    Assert(pVirtio == (PVIRTIOSTATE)pvUser); RT_NOREF(pvUser);
    11861215
     
    12001229         * Callback to client to manage device-specific configuration.
    12011230         */
    1202         VBOXSTRICTRC rcStrict = pVirtio->Callbacks.pfnDevCapRead(pDevIns, offIntra, pv, cb);
     1231        VBOXSTRICTRC rcStrict = pVirtioCC->Callbacks.pfnDevCapRead(pDevIns, offIntra, pv, cb);
    12031232
    12041233        /*
     
    12071236         * order to maintain the config generation (see VirtIO 1.0 spec, section 4.1.4.3.1)
    12081237         */
    1209         bool fDevSpecificFieldChanged = !!memcmp((char *)pVirtio->pvDevSpecificCfg + offIntra,
    1210                                                  (char *)pVirtio->pvPrevDevSpecificCfg + offIntra,
    1211                                                  RT_MIN(cb, pVirtio->cbDevSpecificCfg - offIntra));
    1212 
    1213         memcpy(pVirtio->pvPrevDevSpecificCfg, pVirtio->pvDevSpecificCfg, pVirtio->cbDevSpecificCfg);
     1238        bool fDevSpecificFieldChanged = !!memcmp(pVirtioCC->pbDevSpecificCfg + offIntra,
     1239                                                 pVirtioCC->pbPrevDevSpecificCfg + offIntra,
     1240                                                 RT_MIN(cb, pVirtioCC->cbDevSpecificCfg - offIntra));
     1241
     1242        memcpy(pVirtioCC->pbPrevDevSpecificCfg, pVirtioCC->pbDevSpecificCfg, pVirtioCC->cbDevSpecificCfg);
    12141243
    12151244        if (pVirtio->fGenUpdatePending || fDevSpecificFieldChanged)
     
    12291258
    12301259    if (MATCHES_VIRTIO_CAP_STRUCT(off, cb, offIntra, pVirtio->LocCommonCfgCap))
    1231         return virtioCommonCfgAccessed(pVirtio, false /* fWrite */, offIntra, cb, pv);
     1260        return virtioCommonCfgAccessed(pDevIns, pVirtio, pVirtioCC, false /* fWrite */, offIntra, cb, pv);
    12321261
    12331262    if (MATCHES_VIRTIO_CAP_STRUCT(off, cb, offIntra, pVirtio->LocIsrCap) && cb == sizeof(uint8_t))
     
    12361265        Log6Func(("Read and clear ISR\n"));
    12371266        pVirtio->uISR = 0; /* VirtIO specification requires reads of ISR to clear it */
    1238         virtioLowerInterrupt(pVirtio);
     1267        virtioLowerInterrupt(pDevIns);
    12391268        return VINF_SUCCESS;
    12401269    }
     
    12501279static DECLCALLBACK(VBOXSTRICTRC) virtioMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb)
    12511280{
    1252     PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE);
     1281    PVIRTIOSTATE   pVirtio   = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE);
     1282    PVIRTIOSTATECC pVirtioCC = PDMINS_2_DATA_CC(pDevIns, PVIRTIOSTATECC);
    12531283    Assert(pVirtio == (PVIRTIOSTATE)pvUser); RT_NOREF(pvUser);
    12541284
     
    12681298         * Pass this MMIO write access back to the client to handle
    12691299         */
    1270         return pVirtio->Callbacks.pfnDevCapWrite(pDevIns, offIntra, pv, cb);
     1300        return pVirtioCC->Callbacks.pfnDevCapWrite(pDevIns, offIntra, pv, cb);
    12711301#else
    12721302        return VINF_IOM_R3_MMIO_WRITE;
     
    12751305
    12761306    if (MATCHES_VIRTIO_CAP_STRUCT(off, cb, offIntra, pVirtio->LocCommonCfgCap))
    1277         return virtioCommonCfgAccessed(pVirtio, true /* fWrite */, offIntra, cb, (void *)pv);
     1307        return virtioCommonCfgAccessed(pDevIns, pVirtio, pVirtioCC, true /* fWrite */, offIntra, cb, (void *)pv);
    12781308
    12791309    if (MATCHES_VIRTIO_CAP_STRUCT(off, cb, offIntra, pVirtio->LocIsrCap) && cb == sizeof(uint8_t))
     
    12911321    {
    12921322#ifdef IN_RING3
    1293         virtior3QueueNotified(pVirtio, offIntra / VIRTIO_NOTIFY_OFFSET_MULTIPLIER, *(uint16_t *)pv);
     1323        virtioR3QueueNotified(pVirtio, pVirtioCC, offIntra / VIRTIO_NOTIFY_OFFSET_MULTIPLIER, *(uint16_t *)pv);
    12941324#else
    12951325        return VINF_IOM_R3_MMIO_WRITE;
     
    13091339                                                        uint32_t uAddress, unsigned cb, uint32_t *pu32Value)
    13101340{
    1311     PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE);
     1341    PVIRTIOSTATE   pVirtio   = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE);
     1342    PVIRTIOSTATECC pVirtioCC = PDMINS_2_DATA_CC(pDevIns, PVIRTIOSTATECC);
    13121343    RT_NOREF(pPciDev);
    13131344
     
    13211352         * (the virtio_pci_cfg_cap capability), and access data items.
    13221353         */
    1323         uint32_t uLength = pVirtio->pPciCfgCap->pciCap.uLength;
    1324         uint32_t uOffset = pVirtio->pPciCfgCap->pciCap.uOffset;
    1325         uint8_t  uBar    = pVirtio->pPciCfgCap->pciCap.uBar;
     1354        uint32_t uLength = pVirtioCC->pPciCfgCap->pciCap.uLength;
     1355        uint32_t uOffset = pVirtioCC->pPciCfgCap->pciCap.uOffset;
     1356        uint8_t  uBar    = pVirtioCC->pPciCfgCap->pciCap.uBar;
    13261357
    13271358        if (   (uLength != 1 && uLength != 2 && uLength != 4)
     
    13481379                                                         uint32_t uAddress, unsigned cb, uint32_t u32Value)
    13491380{
    1350     PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE);
     1381    PVIRTIOSTATE   pVirtio   = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE);
     1382    PVIRTIOSTATECC pVirtioCC = PDMINS_2_DATA_CC(pDevIns, PVIRTIOSTATECC);
    13511383    RT_NOREF(pPciDev);
    13521384
     
    13581390         * (the virtio_pci_cfg_cap capability), and access data items. */
    13591391
    1360         uint32_t uLength = pVirtio->pPciCfgCap->pciCap.uLength;
    1361         uint32_t uOffset = pVirtio->pPciCfgCap->pciCap.uOffset;
    1362         uint8_t  uBar    = pVirtio->pPciCfgCap->pciCap.uBar;
     1392        uint32_t uLength = pVirtioCC->pPciCfgCap->pciCap.uLength;
     1393        uint32_t uOffset = pVirtioCC->pPciCfgCap->pciCap.uOffset;
     1394        uint8_t  uBar    = pVirtioCC->pPciCfgCap->pciCap.uBar;
    13631395
    13641396        if (   (uLength != 1 && uLength != 2 && uLength != 4)
     
    13861418 * Called from the FNSSMDEVSAVEEXEC function of the device.
    13871419 *
    1388  * @param   pVirtio     Pointer to the virtio state.
     1420 * @param   pVirtio     Pointer to the shared virtio state.
    13891421 * @param   pHlp        The ring-3 device helpers.
    13901422 * @param   pSSM        The saved state handle.
     
    14291461 * Called from the FNSSMDEVLOADEXEC function of the device.
    14301462 *
    1431  * @param   pVirtio     Pointer to the virtio state.
     1463 * @param   pVirtio     Pointer to the shared virtio state.
    14321464 * @param   pHlp        The ring-3 device helpers.
    14331465 * @param   pSSM        The saved state handle.
     
    15031535 * This should be called from PDMDEVREGR3::pfnReset.
    15041536 *
    1505  * @param   pVirtio     Pointer to the virtio state.
    1506  */
    1507 void virtioR3PropagateResetNotification(PVIRTIOSTATE pVirtio)
     1537 * @param   pDevIns     The device instance.
     1538 * @param   pVirtio     Pointer to the shared virtio state.
     1539 */
     1540void virtioR3PropagateResetNotification(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio)
    15081541{
    15091542    /** @todo r=bird: You probably need to do something here.  See
    15101543     *        virtioScsiR3Reset. */
    1511     RT_NOREF(pVirtio);
     1544    RT_NOREF(pDevIns, pVirtio);
    15121545}
    15131546
     
    15211554 * from stalling after suspend.
    15221555 */
    1523 void virtioR3PropagateResumeNotification(PVIRTIOSTATE pVirtio)
    1524 {
    1525     virtioNotifyGuestDriver(pVirtio, (uint16_t)0 /* idxQueue */, true /* fForce */);
     1556void virtioR3PropagateResumeNotification(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio)
     1557{
     1558    virtioNotifyGuestDriver(pDevIns, pVirtio, 0 /* idxQueue */, true /* fForce */);
    15261559}
    15271560
     
    15301563 * This should be called from PDMDEVREGR3::pfnDestruct.
    15311564 *
    1532  * @param   pVirtio     Pointer to the virtio state.
    15331565 * @param   pDevIns     The device instance.
    1534  */
    1535 void virtioR3Term(PVIRTIOSTATE pVirtio, PPDMDEVINS pDevIns)
    1536 {
    1537     if (pVirtio->pvPrevDevSpecificCfg)
    1538     {
    1539         RTMemFree(pVirtio->pvPrevDevSpecificCfg);
    1540         pVirtio->pvPrevDevSpecificCfg = NULL;
    1541     }
    1542     RT_NOREF(pDevIns);
     1566 * @param   pVirtio     Pointer to the shared virtio state.
     1567 * @param   pVirtioCC   Pointer to the ring-3 virtio state.
     1568 */
     1569void virtioR3Term(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC)
     1570{
     1571    if (pVirtioCC->pbPrevDevSpecificCfg)
     1572    {
     1573        RTMemFree(pVirtioCC->pbPrevDevSpecificCfg);
     1574        pVirtioCC->pbPrevDevSpecificCfg = NULL;
     1575    }
     1576    RT_NOREF(pDevIns, pVirtio);
    15431577}
    15441578
     
    15491583 * This should be called from PDMDEVREGR3::pfnConstruct.
    15501584 *
    1551  * @param   pVirtio                 Pointer to the virtio state.  This must be
    1552  *                                  the first member in the shared device
    1553  *                                  instance data!
    15541585 * @param   pDevIns                 The device instance.
     1586 * @param   pVirtio                 Pointer to the shared virtio state.  This
     1587 *                                  must be the first member in the shared
     1588 *                                  device instance data!
     1589 * @param   pVirtioCC               Pointer to the ring-3 virtio state.  This
     1590 *                                  must be the first member in the ring-3
     1591 *                                  device instance data!
    15551592 * @param   pPciParams              Values to populate industry standard PCI Configuration Space data structure
    15561593 * @param   pcszInstance            Device instance name (format-specifier)
     
    15611598 *                                  configuration struct.
    15621599 */
    1563 int virtioR3Init(PVIRTIOSTATE pVirtio, PPDMDEVINS pDevIns, PVIRTIOPCIPARAMS pPciParams, const char *pcszInstance,
    1564                  uint64_t fDevSpecificFeatures, void *pvDevSpecificCfg, uint16_t cbDevSpecificCfg)
     1600int virtioR3Init(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC, PVIRTIOPCIPARAMS pPciParams,
     1601                 const char *pcszInstance, uint64_t fDevSpecificFeatures, void *pvDevSpecificCfg, uint16_t cbDevSpecificCfg)
    15651602{
    15661603    /*
     
    15691606     */
    15701607    AssertLogRelReturn(pVirtio == PDMINS_2_DATA(pDevIns, PVIRTIOSTATE), VERR_STATE_CHANGED);
     1608    AssertLogRelReturn(pVirtioCC == PDMINS_2_DATA_CC(pDevIns, PVIRTIOSTATECC), VERR_STATE_CHANGED);
    15711609
    15721610
     
    15871625    RTStrCopy(pVirtio->szInstance, sizeof(pVirtio->szInstance), pcszInstance);
    15881626
    1589     pVirtio->pDevInsR3 = pDevIns;
    15901627    pVirtio->uDeviceStatus = 0;
    1591     pVirtio->cbDevSpecificCfg = cbDevSpecificCfg;
    1592     pVirtio->pvDevSpecificCfg = pvDevSpecificCfg;
    1593     pVirtio->pvPrevDevSpecificCfg = RTMemDup(pvDevSpecificCfg, cbDevSpecificCfg);
    1594     AssertLogRelReturn(pVirtio->pvPrevDevSpecificCfg, VERR_NO_MEMORY);
     1628    pVirtioCC->cbDevSpecificCfg = cbDevSpecificCfg;
     1629    pVirtioCC->pbDevSpecificCfg = (uint8_t *)pvDevSpecificCfg;
     1630    pVirtioCC->pbPrevDevSpecificCfg = (uint8_t *)RTMemDup(pvDevSpecificCfg, cbDevSpecificCfg);
     1631    AssertLogRelReturn(pVirtioCC->pbPrevDevSpecificCfg, VERR_NO_MEMORY);
    15951632
    15961633    /* Set PCI config registers (assume 32-bit mode) */
     
    16491686    cbRegion += pCfg->uLength;
    16501687    SET_PCI_CAP_LOC(pPciDev, pCfg, pVirtio->LocCommonCfgCap, 2);
    1651     pVirtio->pCommonCfgCap = pCfg;
     1688    pVirtioCC->pCommonCfgCap = pCfg;
    16521689
    16531690    /*
     
    16611698    pCfg->uCapNext = CFG_ADDR_2_IDX(pCfg) + pCfg->uCapLen;
    16621699    pCfg->uBar     = VIRTIO_REGION_PCI_CAP;
    1663     pCfg->uOffset  = pVirtio->pCommonCfgCap->uOffset + pVirtio->pCommonCfgCap->uLength;
     1700    pCfg->uOffset  = pVirtioCC->pCommonCfgCap->uOffset + pVirtioCC->pCommonCfgCap->uLength;
    16641701    pCfg->uOffset  = RT_ALIGN_32(pCfg->uOffset, 2); /** @todo r=bird: Why is this word aligned rather than dword?  If there is a
    16651702                                                     * theoretical chance we won't allways be on a dword boundrary here, the
     
    16681705    cbRegion += pCfg->uLength;
    16691706    SET_PCI_CAP_LOC(pPciDev, pCfg, pVirtio->LocNotifyCap, 1);
    1670     pVirtio->pNotifyCap = (PVIRTIO_PCI_NOTIFY_CAP_T)pCfg;
    1671     pVirtio->pNotifyCap->uNotifyOffMultiplier = VIRTIO_NOTIFY_OFFSET_MULTIPLIER;
     1707    pVirtioCC->pNotifyCap = (PVIRTIO_PCI_NOTIFY_CAP_T)pCfg;
     1708    pVirtioCC->pNotifyCap->uNotifyOffMultiplier = VIRTIO_NOTIFY_OFFSET_MULTIPLIER;
    16721709
    16731710    /* ISR capability (VirtIO 1.0 spec, section 4.1.4.5)
     
    16831720    pCfg->uCapNext = CFG_ADDR_2_IDX(pCfg) + pCfg->uCapLen;
    16841721    pCfg->uBar     = VIRTIO_REGION_PCI_CAP;
    1685     pCfg->uOffset  = pVirtio->pNotifyCap->pciCap.uOffset + pVirtio->pNotifyCap->pciCap.uLength; /** @todo r=bird: This probably is _not_ dword aligned, given that the previous structure is 0x32 (50) bytes long. */
     1722    pCfg->uOffset  = pVirtioCC->pNotifyCap->pciCap.uOffset + pVirtioCC->pNotifyCap->pciCap.uLength; /** @todo r=bird: This probably is _not_ dword aligned, given that the previous structure is 0x32 (50) bytes long. */
    16861723    pCfg->uLength  = sizeof(uint8_t);
    16871724    cbRegion += pCfg->uLength;
    16881725    SET_PCI_CAP_LOC(pPciDev, pCfg, pVirtio->LocIsrCap, 4);
    1689     pVirtio->pIsrCap = pCfg;
     1726    pVirtioCC->pIsrCap = pCfg;
    16901727
    16911728    /*  PCI Cfg capability (VirtIO 1.0 spec, section 4.1.4.7)
     
    17011738    pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR;
    17021739    pCfg->uCapLen  = sizeof(VIRTIO_PCI_CFG_CAP_T);
    1703     pCfg->uCapNext = (pVirtio->fMsiSupport || pVirtio->pvDevSpecificCfg) ? CFG_ADDR_2_IDX(pCfg) + pCfg->uCapLen : 0;
     1740    pCfg->uCapNext = (pVirtio->fMsiSupport || pVirtioCC->pbDevSpecificCfg) ? CFG_ADDR_2_IDX(pCfg) + pCfg->uCapLen : 0;
    17041741    pCfg->uBar     = 0;
    17051742    pCfg->uOffset  = 0;
     
    17071744    cbRegion += pCfg->uLength;
    17081745    SET_PCI_CAP_LOC(pPciDev, pCfg, pVirtio->LocPciCfgCap, 1);
    1709     pVirtio->pPciCfgCap = (PVIRTIO_PCI_CFG_CAP_T)pCfg;
    1710 
    1711     if (pVirtio->pvDevSpecificCfg)
     1746    pVirtioCC->pPciCfgCap = (PVIRTIO_PCI_CFG_CAP_T)pCfg;
     1747
     1748    if (pVirtioCC->pbDevSpecificCfg)
    17121749    {
    17131750        /* Following capability (via VirtIO 1.0, section 4.1.4.6). Client defines the
     
    17191756        pCfg->uCapNext = pVirtio->fMsiSupport ? CFG_ADDR_2_IDX(pCfg) + pCfg->uCapLen : 0;
    17201757        pCfg->uBar     = VIRTIO_REGION_PCI_CAP;
    1721         pCfg->uOffset  = pVirtio->pIsrCap->uOffset + pVirtio->pIsrCap->uLength;
     1758        pCfg->uOffset  = pVirtioCC->pIsrCap->uOffset + pVirtioCC->pIsrCap->uLength;
    17221759        pCfg->uOffset  = RT_ALIGN_32(pCfg->uOffset, 4);
    17231760        pCfg->uLength  = cbDevSpecificCfg;
    17241761        cbRegion += pCfg->uLength;
    17251762        SET_PCI_CAP_LOC(pPciDev, pCfg, pVirtio->LocDeviceCap, 4);
    1726         //pVirtio->pDeviceCap = pCfg;
     1763        pVirtioCC->pDeviceCap = pCfg;
    17271764    }
    17281765    else
     
    17741811 *
    17751812 * @returns VBox status code.
    1776  * @param   pVirtio     Pointer to the virtio state.  This must be the first
     1813 * @param   pVirtio     Pointer to the shared virtio state.  This must be the first
    17771814 *                      member in the shared device instance data!
    17781815 * @param   pDevIns     The device instance.
  • trunk/src/VBox/Devices/VirtIO/Virtio_1_0.h

    r81662 r81675  
    2525#include <iprt/sg.h>
    2626
    27 /** Pointer to the virt i/o state. */
     27/** Pointer to the shared VirtIO state. */
    2828typedef struct VIRTIOSTATE *PVIRTIOSTATE;
     29/** Pointer to the ring-3 VirtIO state. */
     30typedef struct VIRTIOSTATER3 *PVIRTIOSTATER3;
     31/** Pointer to the ring-0 VirtIO state. */
     32typedef struct VIRTIOSTATER0 *PVIRTIOSTATER0;
     33/** Pointer to the raw-mode VirtIO state. */
     34typedef struct VIRTIOSTATERC *PVIRTIOSTATERC;
     35/** Pointer to the instance data for the current context. */
     36typedef CTX_SUFF(PVIRTIOSTATE) PVIRTIOSTATECC;
     37
    2938
    3039/**
     
    101110      * changes.
    102111      *
    103       * @param   pVirtio    Pointer to virtio state.
     112      * @param   pVirtio    Pointer to the shared virtio state.
     113      * @param   pVirtioCC  Pointer to the ring-3 virtio state.
    104114      * @param   fDriverOk  True if guest driver is okay (thus queues, etc... are
    105115      *                     valid)
    106116      */
    107      DECLCALLBACKMEMBER(void, pfnStatusChanged)(PVIRTIOSTATE pVirtio, uint32_t fDriverOk);
     117     DECLCALLBACKMEMBER(void, pfnStatusChanged)(PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC, uint32_t fDriverOk);
    108118
    109119     /**
     
    111121      * that the avail queue has buffers, and this callback informs the client.
    112122      *
    113       * @param   pVirtio    Pointer to virtio state.
     123      * @param   pVirtio    Pointer to the shared virtio state.
     124      * @param   pVirtioCC  Pointer to the ring-3 virtio state.
    114125      * @param   idxQueue   Index of the notified queue
    115126      */
    116      DECLCALLBACKMEMBER(void, pfnQueueNotified)(PVIRTIOSTATE pVirtio, uint16_t idxQueue);
     127     DECLCALLBACKMEMBER(void, pfnQueueNotified)(PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC, uint16_t idxQueue);
    117128
    118129     /**
     
    254265
    255266/**
    256  * The core (/common) state of the VirtIO PCI device
     267 * The core/common state of the VirtIO PCI devices, shared edition.
    257268 */
    258269typedef struct VIRTIOSTATE
    259270{
    260271    char                        szInstance[16];                     /**< Instance name, e.g. "VIRTIOSCSI0"         */
    261     PPDMDEVINSR3                pDevInsR3;                          /**< Device instance - R3                      */
    262 
    263 #if 0
    264     RTGCPHYS                    GCPhysPciCapBase;                   /**< Pointer to MMIO mapped capability data    */
    265     RTGCPHYS                    GCPhysCommonCfg;                    /**< Pointer to MMIO mapped capability data    */
    266     RTGCPHYS                    GCPhysNotifyCap;                    /**< Pointer to MMIO mapped capability data    */
    267     RTGCPHYS                    GCPhysIsrCap;                       /**< Pointer to MMIO mapped capability data    */
    268     RTGCPHYS                    GCPhysDeviceCap;                    /**< Pointer to MMIO mapped capability data    */
    269 #endif
    270272
    271273    RTGCPHYS                    aGCPhysQueueDesc[VIRTQ_MAX_CNT];    /**< (MMIO) PhysAdr per-Q desc structs   GUEST */
     
    293295
    294296    VIRTQSTATE                  virtqState[VIRTQ_MAX_CNT];          /**< Local impl-specific queue context         */
    295     VIRTIOCALLBACKS             Callbacks;                          /**< Callback vectors to client                */
    296 
    297     R3PTRTYPE(PVIRTIO_PCI_CFG_CAP_T)    pPciCfgCap;                         /**< Pointer to struct in the PCI configuration area. */
    298     R3PTRTYPE(PVIRTIO_PCI_NOTIFY_CAP_T) pNotifyCap;                         /**< Pointer to struct in the PCI configuration area. */
    299     R3PTRTYPE(PVIRTIO_PCI_CAP_T)        pCommonCfgCap;                      /**< Pointer to struct in the PCI configuration area. */
    300     R3PTRTYPE(PVIRTIO_PCI_CAP_T)        pIsrCap;                            /**< Pointer to struct in the PCI configuration area. */
    301     R3PTRTYPE(PVIRTIO_PCI_CAP_T)        pDeviceCap;                         /**< Pointer to struct in the PCI configuration area. */
    302297
    303298    /** @name The locations of the capability structures in PCI config space and the BAR.
     
    310305    /** @} */
    311306
    312     uint32_t                    cbDevSpecificCfg;                   /**< Size of client's dev-specific config data */
    313     void                       *pvDevSpecificCfg;                   /**< Pointer to client's struct                */
    314     void                       *pvPrevDevSpecificCfg;               /**< Previous read dev-specific cfg of client  */
    315307    bool                        fGenUpdatePending;                  /**< If set, update cfg gen after driver reads */
    316308    uint8_t                     uPciCfgDataOff;
     
    324316
    325317
     318/**
     319 * The core/common state of the VirtIO PCI devices, ring-3 edition.
     320 */
     321typedef struct VIRTIOSTATER3
     322{
     323    VIRTIOCALLBACKS             Callbacks;                          /**< Callback vectors to client                */
     324
     325    R3PTRTYPE(PVIRTIO_PCI_CFG_CAP_T)    pPciCfgCap;                 /**< Pointer to struct in the PCI configuration area. */
     326    R3PTRTYPE(PVIRTIO_PCI_NOTIFY_CAP_T) pNotifyCap;                 /**< Pointer to struct in the PCI configuration area. */
     327    R3PTRTYPE(PVIRTIO_PCI_CAP_T)        pCommonCfgCap;              /**< Pointer to struct in the PCI configuration area. */
     328    R3PTRTYPE(PVIRTIO_PCI_CAP_T)        pIsrCap;                    /**< Pointer to struct in the PCI configuration area. */
     329    R3PTRTYPE(PVIRTIO_PCI_CAP_T)        pDeviceCap;                 /**< Pointer to struct in the PCI configuration area. */
     330
     331    uint32_t                    cbDevSpecificCfg;                   /**< Size of client's dev-specific config data */
     332    R3PTRTYPE(uint8_t *)        pbDevSpecificCfg;                   /**< Pointer to client's struct                */
     333    R3PTRTYPE(uint8_t *)        pbPrevDevSpecificCfg;               /**< Previous read dev-specific cfg of client  */
     334    bool                        fGenUpdatePending;                  /**< If set, update cfg gen after driver reads */
     335} VIRTIOSTATER3;
     336
     337
     338/**
     339 * The core/common state of the VirtIO PCI devices, ring-0 edition.
     340 */
     341typedef struct VIRTIOSTATER0
     342{
     343    uint64_t                    uUnusedAtTheMoment;
     344} VIRTIOSTATER0;
     345
     346
     347/**
     348 * The core/common state of the VirtIO PCI devices, raw-mode edition.
     349 */
     350typedef struct VIRTIOSTATERC
     351{
     352    uint64_t                    uUnusedAtTheMoment;
     353} VIRTIOSTATERC;
     354
     355
     356/** @typedef VIRTIOSTATECC
     357 * The instance data for the current context. */
     358typedef CTX_SUFF(VIRTIOSTATE) VIRTIOSTATECC;
     359
     360
    326361/** virtq related flags */
    327362#define VIRTQ_DESC_F_NEXT                               1        /**< Indicates this descriptor chains to next  */
     
    346381int virtioQueueDetach(PVIRTIOSTATE pVirtio, uint16_t idxQueue);
    347382#endif
    348 int  virtioR3QueueGet(PVIRTIOSTATE pVirtio, uint16_t idxQueue, PPVIRTIO_DESC_CHAIN_T ppDescChain, bool fRemove);
    349 int  virtioR3QueuePut(PVIRTIOSTATE pVirtio, uint16_t idxQueue, PRTSGBUF pSgVirtReturn,
     383int  virtioR3QueueGet(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue,
     384                      PPVIRTIO_DESC_CHAIN_T ppDescChain, bool fRemove);
     385int  virtioR3QueuePut(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, PRTSGBUF pSgVirtReturn,
    350386                      PVIRTIO_DESC_CHAIN_T pDescChain, bool fFence);
    351 
    352 int virtioQueueSync(PVIRTIOSTATE pVirtio, uint16_t idxQueue);
    353 bool virtioQueueIsEmpty(PVIRTIOSTATE pVirtio, uint16_t idxQueue);
    354 
     387int  virtioQueueSync(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue);
     388bool virtioQueueIsEmpty(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue);
    355389void virtioQueueEnable(PVIRTIOSTATE pVirtio, uint16_t idxQueue, bool fEnabled);
     390
     391#if 0 /** @todo unused */
    356392void virtioResetAll(PVIRTIOSTATE pVirtio);
     393#endif
    357394
    358395/**
     
    409446int  virtioR3SaveExec(PVIRTIOSTATE pVirtio, PCPDMDEVHLPR3 pHlp, PSSMHANDLE pSSM);
    410447int  virtioR3LoadExec(PVIRTIOSTATE pVirtio, PCPDMDEVHLPR3 pHlp, PSSMHANDLE pSSM);
    411 void virtioR3PropagateResetNotification(PVIRTIOSTATE pVirtio);
    412 void virtioR3PropagateResumeNotification(PVIRTIOSTATE pVirtio);
    413 void virtioR3Term(PVIRTIOSTATE pVirtio, PPDMDEVINS pDevIns);
    414 int  virtioR3Init(PVIRTIOSTATE pVirtio, PPDMDEVINS pDevIns, PVIRTIOPCIPARAMS pPciParams, const char *pcszInstance,
    415                   uint64_t fDevSpecificFeatures, void *pvDevSpecificCfg, uint16_t cbDevSpecificCfg);
     448void virtioR3PropagateResetNotification(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio);
     449void virtioR3PropagateResumeNotification(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio);
     450void virtioR3Term(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC);
     451int  virtioR3Init(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC, PVIRTIOPCIPARAMS pPciParams,
     452                  const char *pcszInstance, uint64_t fDevSpecificFeatures, void *pvDevSpecificCfg, uint16_t cbDevSpecificCfg);
    416453
    417454void virtioLogMappedIoValue(const char *pszFunc, const char *pszMember, uint32_t uMemberSize,
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette