VirtualBox

Changeset 63951 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Sep 22, 2016 2:29:22 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
110837
Message:

DrvVD: More work on the extended media interface to bring it up to par with the older async interface so we can start replacing PDMIMEDIAASYNC with the new interface

File:
1 edited

Legend:

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

    r63919 r63951  
    411411static void drvvdPowerOffOrDestructOrUnmount(PPDMDRVINS pDrvIns);
    412412DECLINLINE(void) drvvdMediaExIoReqBufFree(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq);
     413static int drvvdMediaExIoReqCompleteWorker(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq, int rcReq, bool fUpNotify);
    413414static int drvvdMediaExIoReqReadWriteProcess(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq, bool fUpNotify);
    414415
     
    501502
    502503static DECLCALLBACK(void) drvvdErrorCallback(void *pvUser, int rc, RT_SRC_POS_DECL,
    503                                const char *pszFormat, va_list va)
     504                                             const char *pszFormat, va_list va)
    504505{
    505506    PPDMDRVINS pDrvIns = (PPDMDRVINS)pvUser;
     
    25032504*********************************************************************************************************************************/
    25042505
     2506static DECLCALLBACK(void) drvvdBlkCacheReqComplete(void *pvUser1, void *pvUser2, int rcReq)
     2507{
     2508    PVBOXDISK pThis = (PVBOXDISK)pvUser1;
     2509
     2510    AssertPtr(pThis->pBlkCache);
     2511    PDMR3BlkCacheIoXferComplete(pThis->pBlkCache, (PPDMBLKCACHEIOXFER)pvUser2, rcReq);   
     2512}
     2513
    25052514static DECLCALLBACK(void) drvvdAsyncReqComplete(void *pvUser1, void *pvUser2, int rcReq)
    25062515{
    25072516    PVBOXDISK pThis = (PVBOXDISK)pvUser1;
    25082517
    2509     if (!pThis->pBlkCache)
    2510     {
    2511         int rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort,
    2512                                                                       pvUser2, rcReq);
    2513         AssertRC(rc);
    2514     }
    2515     else
    2516         PDMR3BlkCacheIoXferComplete(pThis->pBlkCache, (PPDMBLKCACHEIOXFER)pvUser2, rcReq);
     2518    int rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort,
     2519                                                                  pvUser2, rcReq);
     2520    AssertRC(rc);
    25172521}
    25182522
     
    26792683}
    26802684
     2685/** @copydoc FNPDMBLKCACHEXFERCOMPLETEDRV */
     2686static DECLCALLBACK(void) drvvdBlkCacheXferCompleteIoReq(PPDMDRVINS pDrvIns, void *pvUser, int rcReq)
     2687{
     2688    PVBOXDISK pThis = PDMINS_2_DATA(pDrvIns, PVBOXDISK);
     2689
     2690    drvvdMediaExIoReqCompleteWorker(pThis, (PPDMMEDIAEXIOREQINT)pvUser, rcReq, true /* fUpNotify */);
     2691}
     2692
    26812693/** @copydoc FNPDMBLKCACHEXFERENQUEUEDRV */
    26822694static DECLCALLBACK(int) drvvdBlkCacheXferEnqueue(PPDMDRVINS pDrvIns,
     
    26932705    {
    26942706        case PDMBLKCACHEXFERDIR_READ:
    2695             rc = VDAsyncRead(pThis->pDisk, off, cbXfer, pcSgBuf, drvvdAsyncReqComplete,
     2707            rc = VDAsyncRead(pThis->pDisk, off, cbXfer, pcSgBuf, drvvdBlkCacheReqComplete,
    26962708                             pThis, hIoXfer);
    26972709            break;
    26982710        case PDMBLKCACHEXFERDIR_WRITE:
    2699             rc = VDAsyncWrite(pThis->pDisk, off, cbXfer, pcSgBuf, drvvdAsyncReqComplete,
     2711            rc = VDAsyncWrite(pThis->pDisk, off, cbXfer, pcSgBuf, drvvdBlkCacheReqComplete,
    27002712                              pThis, hIoXfer);
    27012713            break;
    27022714        case PDMBLKCACHEXFERDIR_FLUSH:
    2703             rc = VDAsyncFlush(pThis->pDisk, drvvdAsyncReqComplete, pThis, hIoXfer);
     2715            rc = VDAsyncFlush(pThis->pDisk, drvvdBlkCacheReqComplete, pThis, hIoXfer);
    27042716            break;
    27052717        default:
     
    27242736
    27252737    rc = VDAsyncDiscardRanges(pThis->pDisk, paRanges, cRanges,
    2726                               drvvdAsyncReqComplete, pThis, hIoXfer);
     2738                              drvvdBlkCacheReqComplete, pThis, hIoXfer);
    27272739
    27282740    if (rc == VINF_VD_ASYNC_IO_FINISHED)
     
    31033115}
    31043116
     3117/**
     3118 * Wrapper around the various ways to read from the underlying medium (cache, async vs. sync).
     3119 *
     3120 * @returns VBox status code.
     3121 * @param   pThis     VBox disk container instance data.
     3122 * @param   pIoReq    I/O request to process.
     3123 * @param   cbReqIo   Transfer size.
     3124 * @param   pcbReqIo  Where to store the amount of transferred data.
     3125 */
     3126static int drvvdMediaExIoReqReadWrapper(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq, size_t cbReqIo, size_t *pcbReqIo)
     3127{
     3128    int rc = VINF_SUCCESS;
     3129
     3130    if (pThis->fAsyncIOSupported)
     3131    {
     3132        if (pThis->pBlkCache)
     3133            rc = PDMR3BlkCacheRead(pThis->pBlkCache, pIoReq->ReadWrite.offStart,
     3134                                   &pIoReq->ReadWrite.IoBuf.SgBuf, cbReqIo, pIoReq);
     3135        else
     3136            rc = VDAsyncRead(pThis->pDisk, pIoReq->ReadWrite.offStart, cbReqIo, &pIoReq->ReadWrite.IoBuf.SgBuf,
     3137                             drvvdMediaExIoReqComplete, pThis, pIoReq);
     3138    }
     3139    else
     3140    {
     3141        void *pvBuf = RTSgBufGetNextSegment(&pIoReq->ReadWrite.IoBuf.SgBuf, &cbReqIo);
     3142
     3143        Assert(cbReqIo > 0 && VALID_PTR(pvBuf));
     3144        rc = VDRead(pThis->pDisk, pIoReq->ReadWrite.offStart, pvBuf, cbReqIo);
     3145        if (RT_SUCCESS(rc))
     3146            rc = VINF_VD_ASYNC_IO_FINISHED;
     3147    }
     3148
     3149    *pcbReqIo = cbReqIo;
     3150
     3151    return rc;
     3152}
     3153
     3154/**
     3155 * Wrapper around the various ways to write to the underlying medium (cache, async vs. sync).
     3156 *
     3157 * @returns VBox status code.
     3158 * @param   pThis     VBox disk container instance data.
     3159 * @param   pIoReq    I/O request to process.
     3160 * @param   cbReqIo   Transfer size.
     3161 * @param   pcbReqIo  Where to store the amount of transferred data.
     3162 */
     3163static int drvvdMediaExIoReqWriteWrapper(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq, size_t cbReqIo, size_t *pcbReqIo)
     3164{
     3165    int rc = VINF_SUCCESS;
     3166
     3167    if (pThis->fAsyncIOSupported)
     3168    {
     3169        if (pThis->pBlkCache)
     3170            rc = PDMR3BlkCacheWrite(pThis->pBlkCache, pIoReq->ReadWrite.offStart,
     3171                                    &pIoReq->ReadWrite.IoBuf.SgBuf, cbReqIo, pIoReq);
     3172        else
     3173            rc = VDAsyncWrite(pThis->pDisk, pIoReq->ReadWrite.offStart, cbReqIo, &pIoReq->ReadWrite.IoBuf.SgBuf,
     3174                              drvvdMediaExIoReqComplete, pThis, pIoReq);
     3175    }
     3176    else
     3177    {
     3178        void *pvBuf = RTSgBufGetNextSegment(&pIoReq->ReadWrite.IoBuf.SgBuf, &cbReqIo);
     3179
     3180        Assert(cbReqIo > 0 && VALID_PTR(pvBuf));
     3181        rc = VDWrite(pThis->pDisk, pIoReq->ReadWrite.offStart, pvBuf, cbReqIo);
     3182        if (RT_SUCCESS(rc))
     3183            rc = VINF_VD_ASYNC_IO_FINISHED;
     3184    }
     3185
     3186    *pcbReqIo = cbReqIo;
     3187
     3188    return rc;
     3189}
     3190
     3191/**
     3192 * Wrapper around the various ways to flush all data to the underlying medium (cache, async vs. sync).
     3193 *
     3194 * @returns VBox status code.
     3195 * @param   pThis     VBox disk container instance data.
     3196 * @param   pIoReq    I/O request to process.
     3197 */
     3198static int drvvdMediaExIoReqFlushWrapper(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq)
     3199{
     3200    int rc = VINF_SUCCESS;
     3201
     3202    if (pThis->fAsyncIOSupported)
     3203    {
     3204        if (pThis->pBlkCache)
     3205            rc = PDMR3BlkCacheFlush(pThis->pBlkCache, pIoReq);
     3206        else
     3207            rc = VDAsyncFlush(pThis->pDisk, drvvdMediaExIoReqComplete, pThis, pIoReq);
     3208    }
     3209    else
     3210    {
     3211        rc = VDFlush(pThis->pDisk);
     3212        if (RT_SUCCESS(rc))
     3213            rc = VINF_VD_ASYNC_IO_FINISHED;
     3214    }
     3215
     3216    return rc;
     3217}
     3218
     3219/**
     3220 * Wrapper around the various ways to discard data blocks on the underlying medium (cache, async vs. sync).
     3221 *
     3222 * @returns VBox status code.
     3223 * @param   pThis     VBox disk container instance data.
     3224 * @param   pIoReq    I/O request to process.
     3225 */
     3226static int drvvdMediaExIoReqDiscardWrapper(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq)
     3227{
     3228    int rc = VINF_SUCCESS;
     3229
     3230    if (pThis->fAsyncIOSupported)
     3231    {
     3232        if (pThis->pBlkCache)
     3233            rc = PDMR3BlkCacheDiscard(pThis->pBlkCache, pIoReq->Discard.paRanges, pIoReq->Discard.cRanges, pIoReq);
     3234        else
     3235            rc = VDAsyncDiscardRanges(pThis->pDisk, pIoReq->Discard.paRanges, pIoReq->Discard.cRanges,
     3236                                      drvvdMediaExIoReqComplete, pThis, pIoReq);
     3237    }
     3238    else
     3239    {
     3240        rc = VDDiscardRanges(pThis->pDisk, pIoReq->Discard.paRanges, pIoReq->Discard.cRanges);
     3241        if (RT_SUCCESS(rc))
     3242            rc = VINF_VD_ASYNC_IO_FINISHED;
     3243    }
     3244
     3245    return rc;
     3246}
    31053247
    31063248/**
     
    31263268
    31273269        if (pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ)
    3128         {
    3129             if (pThis->fAsyncIOSupported)
    3130                 rc = VDAsyncRead(pThis->pDisk, pIoReq->ReadWrite.offStart, cbReqIo, &pIoReq->ReadWrite.IoBuf.SgBuf,
    3131                                  drvvdMediaExIoReqComplete, pThis, pIoReq);
    3132             else
    3133             {
    3134                 void *pvBuf = RTSgBufGetNextSegment(&pIoReq->ReadWrite.IoBuf.SgBuf, &cbReqIo);
    3135 
    3136                 Assert(cbReqIo > 0 && VALID_PTR(pvBuf));
    3137                 rc = VDRead(pThis->pDisk, pIoReq->ReadWrite.offStart, pvBuf, cbReqIo);
    3138                 if (RT_SUCCESS(rc))
    3139                     rc = VINF_VD_ASYNC_IO_FINISHED;
    3140             }
    3141         }
     3270            rc = drvvdMediaExIoReqReadWrapper(pThis, pIoReq, cbReqIo, &cbReqIo);
    31423271        else
    31433272        {
     
    31453274            rc = drvvdMediaExIoReqBufSync(pThis, pIoReq, true /* fToIoBuf */);
    31463275            if (RT_SUCCESS(rc))
    3147             {
    3148                 if (pThis->fAsyncIOSupported)
    3149                     rc = VDAsyncWrite(pThis->pDisk, pIoReq->ReadWrite.offStart, cbReqIo,
    3150                                       &pIoReq->ReadWrite.IoBuf.SgBuf,
    3151                                       drvvdMediaExIoReqComplete, pThis, pIoReq);
    3152                 else
    3153                 {
    3154                     void *pvBuf = RTSgBufGetNextSegment(&pIoReq->ReadWrite.IoBuf.SgBuf, &cbReqIo);
    3155 
    3156                     Assert(cbReqIo > 0 && VALID_PTR(pvBuf));
    3157                     rc = VDWrite(pThis->pDisk, pIoReq->ReadWrite.offStart, pvBuf, cbReqIo);
    3158                     if (RT_SUCCESS(rc))
    3159                         rc = VINF_VD_ASYNC_IO_FINISHED;
    3160                 }
    3161             }
     3276                rc = drvvdMediaExIoReqWriteWrapper(pThis, pIoReq, cbReqIo, &cbReqIo);
    31623277        }
    31633278
     
    32743389
    32753390/**
     3391 * Tries to cancel the given I/O request returning the result.
     3392 *
     3393 * @returns Flag whether the request was successfully canceled or whether it
     3394 *          already complete inbetween.
     3395 * @param   pThis     VBox disk container instance data.
     3396 * @param   pIoReq    The I/O request to cancel.
     3397 */
     3398static bool drvvdMediaExIoReqCancel(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq)
     3399{
     3400    bool fXchg = true;
     3401    VDIOREQSTATE enmStateOld = (VDIOREQSTATE)ASMAtomicReadU32((volatile uint32_t *)&pIoReq->enmState);
     3402
     3403    /*
     3404     * We might have to try canceling the request multiple times if it transitioned from
     3405     * ALLOCATED to ACTIVE or to SUSPENDED between reading the state and trying to change it.
     3406     */
     3407    while (   (   enmStateOld == VDIOREQSTATE_ALLOCATED
     3408               || enmStateOld == VDIOREQSTATE_ACTIVE
     3409               || enmStateOld == VDIOREQSTATE_SUSPENDED)
     3410           && !fXchg)
     3411    {
     3412        fXchg = ASMAtomicCmpXchgU32((volatile uint32_t *)&pIoReq->enmState, VDIOREQSTATE_CANCELED, enmStateOld);
     3413        if (!fXchg)
     3414            enmStateOld = (VDIOREQSTATE)ASMAtomicReadU32((volatile uint32_t *)&pIoReq->enmState);
     3415    }
     3416
     3417    if (fXchg)
     3418        ASMAtomicDecU32(&pThis->cIoReqsActive);
     3419
     3420    return fXchg;
     3421}
     3422
     3423/**
     3424 * @interface_method_impl{PDMIMEDIAEX,pfnQueryFeatures}
     3425 */
     3426static DECLCALLBACK(int) drvvdQueryFeatures(PPDMIMEDIAEX pInterface, uint32_t *pfFeatures)
     3427{
     3428    PVBOXDISK pThis = RT_FROM_MEMBER(pInterface, VBOXDISK, IMediaEx);
     3429
     3430    AssertPtrReturn(pfFeatures, VERR_INVALID_POINTER);
     3431
     3432    uint32_t fFeatures = 0;
     3433    if (pThis->fAsyncIOSupported)
     3434        fFeatures |= PDMIMEDIAEX_FEATURE_F_ASYNC;
     3435    if (pThis->IMedia.pfnDiscard)
     3436        fFeatures |= PDMIMEDIAEX_FEATURE_F_DISCARD;
     3437
     3438    *pfFeatures = fFeatures;
     3439
     3440    return VINF_SUCCESS;
     3441}
     3442
     3443
     3444/**
    32763445 * @interface_method_impl{PDMIMEDIAEX,pfnIoReqAllocSizeSet}
    32773446 */
     
    33533522
    33543523/**
     3524 * @interface_method_impl{PDMIMEDIAEX,pfnIoReqCancelAll}
     3525 */
     3526static DECLCALLBACK(int) drvvdIoReqCancelAll(PPDMIMEDIAEX pInterface)
     3527{
     3528    int rc = VINF_SUCCESS;
     3529    PVBOXDISK pThis = RT_FROM_MEMBER(pInterface, VBOXDISK, IMediaEx);
     3530
     3531    for (unsigned idxBin = 0; idxBin < RT_ELEMENTS(pThis->aIoReqAllocBins); idxBin++)
     3532    {
     3533        rc = RTSemFastMutexRequest(pThis->aIoReqAllocBins[idxBin].hMtxLstIoReqAlloc);
     3534        if (RT_SUCCESS(rc))
     3535        {
     3536            /* Search for I/O request with ID. */
     3537            PPDMMEDIAEXIOREQINT pIt;
     3538
     3539            RTListForEach(&pThis->aIoReqAllocBins[idxBin].LstIoReqAlloc, pIt, PDMMEDIAEXIOREQINT, NdAllocatedList)
     3540            {
     3541                drvvdMediaExIoReqCancel(pThis, pIt);
     3542            }
     3543            RTSemFastMutexRelease(pThis->aIoReqAllocBins[idxBin].hMtxLstIoReqAlloc);
     3544        }
     3545    }
     3546
     3547    return rc;
     3548}
     3549
     3550/**
    33553551 * @interface_method_impl{PDMIMEDIAEX,pfnIoReqCancel}
    33563552 */
     
    33713567            if (pIt->uIoReqId == uIoReqId)
    33723568            {
    3373                 bool fXchg = true;
    3374                 VDIOREQSTATE enmStateOld = (VDIOREQSTATE)ASMAtomicReadU32((volatile uint32_t *)&pIt->enmState);
    3375 
    3376                 /*
    3377                  * We might have to try canceling the request multiple times if it transitioned from
    3378                  * ALLOCATED to ACTIVE or to SUSPENDED between reading the state and trying to change it.
    3379                  */
    3380                 while (   (   enmStateOld == VDIOREQSTATE_ALLOCATED
    3381                            || enmStateOld == VDIOREQSTATE_ACTIVE
    3382                            || enmStateOld == VDIOREQSTATE_SUSPENDED)
    3383                        && !fXchg)
    3384                 {
    3385                     fXchg = ASMAtomicCmpXchgU32((volatile uint32_t *)&pIt->enmState, VDIOREQSTATE_CANCELED, enmStateOld);
    3386                     if (!fXchg)
    3387                         enmStateOld = (VDIOREQSTATE)ASMAtomicReadU32((volatile uint32_t *)&pIt->enmState);
    3388                 }
    3389 
    3390                 if (fXchg)
    3391                 {
    3392                     ASMAtomicDecU32(&pThis->cIoReqsActive);
     3569                if (drvvdMediaExIoReqCancel(pThis, pIt))
    33933570                    rc = VINF_SUCCESS;
    3394                 }
     3571
    33953572                break;
    33963573            }
     
    35063683
    35073684    ASMAtomicIncU32(&pThis->cIoReqsActive);
    3508     int rc = VINF_SUCCESS;
    3509     if (pThis->fAsyncIOSupported)
    3510         rc = VDAsyncFlush(pThis->pDisk, drvvdMediaExIoReqComplete, pThis, pIoReq);
    3511     else
    3512         rc = VDFlush(pThis->pDisk);
    3513 
     3685    int rc = drvvdMediaExIoReqFlushWrapper(pThis, pIoReq);
    35143686    if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
    35153687        rc = VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS;
     
    35543726
    35553727    ASMAtomicIncU32(&pThis->cIoReqsActive);
    3556     int rc = VDAsyncDiscardRanges(pThis->pDisk, paRanges, cRanges,
    3557                                   drvvdMediaExIoReqComplete, pThis, pIoReq);
     3728    int rc = drvvdMediaExIoReqDiscardWrapper(pThis, pIoReq);
    35583729    if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
    35593730        rc = VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS;
     
    35653736
    35663737    return rc;
     3738}
     3739
     3740/**
     3741 * @interface_method_impl{PDMIMEDIAEX,pfnIoReqSendScsiCmd}
     3742 */
     3743static DECLCALLBACK(int) drvvdIoReqSendScsiCmd(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, const uint8_t *pbCmd, PDMMEDIATXDIR enmTxDir,
     3744                                               size_t cbBuf, uint8_t *pabSense, size_t cbSense, uint32_t cTimeoutMillies)
     3745{
     3746    RT_NOREF7(pInterface, pbCmd, enmTxDir, cbBuf, pabSense, cbSense, cTimeoutMillies);
     3747    PPDMMEDIAEXIOREQINT pIoReq = hIoReq;
     3748    VDIOREQSTATE enmState = (VDIOREQSTATE)ASMAtomicReadU32((volatile uint32_t *)&pIoReq->enmState);
     3749
     3750    if (RT_UNLIKELY(enmState == VDIOREQSTATE_CANCELED))
     3751        return VERR_PDM_MEDIAEX_IOREQ_CANCELED;
     3752
     3753    if (RT_UNLIKELY(enmState != VDIOREQSTATE_ALLOCATED))
     3754        return VERR_PDM_MEDIAEX_IOREQ_INVALID_STATE;
     3755
     3756    return VERR_NOT_SUPPORTED;
    35673757}
    35683758
     
    40794269                else if (pIoReq->enmType == PDMMEDIAEXIOREQTYPE_FLUSH)
    40804270                {
    4081                     rc = VDAsyncFlush(pThis->pDisk, drvvdMediaExIoReqComplete, pThis, pIoReq);
     4271                    rc = drvvdMediaExIoReqFlushWrapper(pThis, pIoReq);
    40824272                    if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
    40834273                        rc = VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS;
     
    40874277                else if (pIoReq->enmType == PDMMEDIAEXIOREQTYPE_DISCARD)
    40884278                {
    4089                     rc = VDAsyncDiscardRanges(pThis->pDisk, pIoReq->Discard.paRanges, pIoReq->Discard.cRanges,
    4090                                               drvvdMediaExIoReqComplete, pThis, pIoReq);
     4279                    rc = drvvdMediaExIoReqDiscardWrapper(pThis, pIoReq);
    40914280                    if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
    40924281                        rc = VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS;
     
    43074496
    43084497    /* IMediaEx */
     4498    pThis->IMediaEx.pfnQueryFeatures            = drvvdQueryFeatures;
    43094499    pThis->IMediaEx.pfnIoReqAllocSizeSet        = drvvdIoReqAllocSizeSet;
    43104500    pThis->IMediaEx.pfnIoReqAlloc               = drvvdIoReqAlloc;
    43114501    pThis->IMediaEx.pfnIoReqFree                = drvvdIoReqFree;
     4502    pThis->IMediaEx.pfnIoReqCancelAll           = drvvdIoReqCancelAll;
    43124503    pThis->IMediaEx.pfnIoReqCancel              = drvvdIoReqCancel;
    43134504    pThis->IMediaEx.pfnIoReqRead                = drvvdIoReqRead;
     
    43154506    pThis->IMediaEx.pfnIoReqFlush               = drvvdIoReqFlush;
    43164507    pThis->IMediaEx.pfnIoReqDiscard             = drvvdIoReqDiscard;
     4508    pThis->IMediaEx.pfnIoReqSendScsiCmd         = drvvdIoReqSendScsiCmd;
    43174509    pThis->IMediaEx.pfnIoReqGetActiveCount      = drvvdIoReqGetActiveCount;
    43184510    pThis->IMediaEx.pfnIoReqGetSuspendedCount   = drvvdIoReqGetSuspendedCount;
     
    49905182            if (!fDiscard)
    49915183            {
    4992                 pThis->IMedia.pfnDiscard = NULL;
     5184                pThis->IMedia.pfnDiscard           = NULL;
    49935185                pThis->IMediaAsync.pfnStartDiscard = NULL;
     5186                pThis->IMediaEx.pfnIoReqDiscard    = NULL;
    49945187            }
    49955188
     
    51125305                if (cbStr > 0)
    51135306                {
     5307                    bool fMediaEx = strcmp(pcszController, "nvme") == 0 ? true : false;
    51145308                    rc = PDMDrvHlpBlkCacheRetain(pDrvIns, &pThis->pBlkCache,
    5115                                                  drvvdBlkCacheXferComplete,
     5309                                                 fMediaEx ? drvvdBlkCacheXferCompleteIoReq
     5310                                                          : drvvdBlkCacheXferComplete,
    51165311                                                 drvvdBlkCacheXferEnqueue,
    51175312                                                 drvvdBlkCacheXferEnqueueDiscard,
     
    51385333        /*
    51395334         * Register a load-done callback so we can undo TempReadOnly config before
    5140          * we get to drvvdResume.  Autoamtically deregistered upon destruction.
     5335         * we get to drvvdResume.  Automatically deregistered upon destruction.
    51415336         */
    51425337        if (RT_SUCCESS(rc))
Note: See TracChangeset for help on using the changeset viewer.

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