Changeset 63951 in vbox for trunk/src/VBox
- Timestamp:
- Sep 22, 2016 2:29:22 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 110837
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DrvVD.cpp
r63919 r63951 411 411 static void drvvdPowerOffOrDestructOrUnmount(PPDMDRVINS pDrvIns); 412 412 DECLINLINE(void) drvvdMediaExIoReqBufFree(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq); 413 static int drvvdMediaExIoReqCompleteWorker(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq, int rcReq, bool fUpNotify); 413 414 static int drvvdMediaExIoReqReadWriteProcess(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq, bool fUpNotify); 414 415 … … 501 502 502 503 static 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) 504 505 { 505 506 PPDMDRVINS pDrvIns = (PPDMDRVINS)pvUser; … … 2503 2504 *********************************************************************************************************************************/ 2504 2505 2506 static 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 2505 2514 static DECLCALLBACK(void) drvvdAsyncReqComplete(void *pvUser1, void *pvUser2, int rcReq) 2506 2515 { 2507 2516 PVBOXDISK pThis = (PVBOXDISK)pvUser1; 2508 2517 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); 2517 2521 } 2518 2522 … … 2679 2683 } 2680 2684 2685 /** @copydoc FNPDMBLKCACHEXFERCOMPLETEDRV */ 2686 static 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 2681 2693 /** @copydoc FNPDMBLKCACHEXFERENQUEUEDRV */ 2682 2694 static DECLCALLBACK(int) drvvdBlkCacheXferEnqueue(PPDMDRVINS pDrvIns, … … 2693 2705 { 2694 2706 case PDMBLKCACHEXFERDIR_READ: 2695 rc = VDAsyncRead(pThis->pDisk, off, cbXfer, pcSgBuf, drvvd AsyncReqComplete,2707 rc = VDAsyncRead(pThis->pDisk, off, cbXfer, pcSgBuf, drvvdBlkCacheReqComplete, 2696 2708 pThis, hIoXfer); 2697 2709 break; 2698 2710 case PDMBLKCACHEXFERDIR_WRITE: 2699 rc = VDAsyncWrite(pThis->pDisk, off, cbXfer, pcSgBuf, drvvd AsyncReqComplete,2711 rc = VDAsyncWrite(pThis->pDisk, off, cbXfer, pcSgBuf, drvvdBlkCacheReqComplete, 2700 2712 pThis, hIoXfer); 2701 2713 break; 2702 2714 case PDMBLKCACHEXFERDIR_FLUSH: 2703 rc = VDAsyncFlush(pThis->pDisk, drvvd AsyncReqComplete, pThis, hIoXfer);2715 rc = VDAsyncFlush(pThis->pDisk, drvvdBlkCacheReqComplete, pThis, hIoXfer); 2704 2716 break; 2705 2717 default: … … 2724 2736 2725 2737 rc = VDAsyncDiscardRanges(pThis->pDisk, paRanges, cRanges, 2726 drvvd AsyncReqComplete, pThis, hIoXfer);2738 drvvdBlkCacheReqComplete, pThis, hIoXfer); 2727 2739 2728 2740 if (rc == VINF_VD_ASYNC_IO_FINISHED) … … 3103 3115 } 3104 3116 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 */ 3126 static 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 */ 3163 static 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 */ 3198 static 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 */ 3226 static 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 } 3105 3247 3106 3248 /** … … 3126 3268 3127 3269 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); 3142 3271 else 3143 3272 { … … 3145 3274 rc = drvvdMediaExIoReqBufSync(pThis, pIoReq, true /* fToIoBuf */); 3146 3275 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); 3162 3277 } 3163 3278 … … 3274 3389 3275 3390 /** 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 */ 3398 static 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 */ 3426 static 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 /** 3276 3445 * @interface_method_impl{PDMIMEDIAEX,pfnIoReqAllocSizeSet} 3277 3446 */ … … 3353 3522 3354 3523 /** 3524 * @interface_method_impl{PDMIMEDIAEX,pfnIoReqCancelAll} 3525 */ 3526 static 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 /** 3355 3551 * @interface_method_impl{PDMIMEDIAEX,pfnIoReqCancel} 3356 3552 */ … … 3371 3567 if (pIt->uIoReqId == uIoReqId) 3372 3568 { 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)) 3393 3570 rc = VINF_SUCCESS; 3394 } 3571 3395 3572 break; 3396 3573 } … … 3506 3683 3507 3684 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); 3514 3686 if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 3515 3687 rc = VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS; … … 3554 3726 3555 3727 ASMAtomicIncU32(&pThis->cIoReqsActive); 3556 int rc = VDAsyncDiscardRanges(pThis->pDisk, paRanges, cRanges, 3557 drvvdMediaExIoReqComplete, pThis, pIoReq); 3728 int rc = drvvdMediaExIoReqDiscardWrapper(pThis, pIoReq); 3558 3729 if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 3559 3730 rc = VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS; … … 3565 3736 3566 3737 return rc; 3738 } 3739 3740 /** 3741 * @interface_method_impl{PDMIMEDIAEX,pfnIoReqSendScsiCmd} 3742 */ 3743 static 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; 3567 3757 } 3568 3758 … … 4079 4269 else if (pIoReq->enmType == PDMMEDIAEXIOREQTYPE_FLUSH) 4080 4270 { 4081 rc = VDAsyncFlush(pThis->pDisk, drvvdMediaExIoReqComplete,pThis, pIoReq);4271 rc = drvvdMediaExIoReqFlushWrapper(pThis, pIoReq); 4082 4272 if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 4083 4273 rc = VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS; … … 4087 4277 else if (pIoReq->enmType == PDMMEDIAEXIOREQTYPE_DISCARD) 4088 4278 { 4089 rc = VDAsyncDiscardRanges(pThis->pDisk, pIoReq->Discard.paRanges, pIoReq->Discard.cRanges, 4090 drvvdMediaExIoReqComplete, pThis, pIoReq); 4279 rc = drvvdMediaExIoReqDiscardWrapper(pThis, pIoReq); 4091 4280 if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 4092 4281 rc = VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS; … … 4307 4496 4308 4497 /* IMediaEx */ 4498 pThis->IMediaEx.pfnQueryFeatures = drvvdQueryFeatures; 4309 4499 pThis->IMediaEx.pfnIoReqAllocSizeSet = drvvdIoReqAllocSizeSet; 4310 4500 pThis->IMediaEx.pfnIoReqAlloc = drvvdIoReqAlloc; 4311 4501 pThis->IMediaEx.pfnIoReqFree = drvvdIoReqFree; 4502 pThis->IMediaEx.pfnIoReqCancelAll = drvvdIoReqCancelAll; 4312 4503 pThis->IMediaEx.pfnIoReqCancel = drvvdIoReqCancel; 4313 4504 pThis->IMediaEx.pfnIoReqRead = drvvdIoReqRead; … … 4315 4506 pThis->IMediaEx.pfnIoReqFlush = drvvdIoReqFlush; 4316 4507 pThis->IMediaEx.pfnIoReqDiscard = drvvdIoReqDiscard; 4508 pThis->IMediaEx.pfnIoReqSendScsiCmd = drvvdIoReqSendScsiCmd; 4317 4509 pThis->IMediaEx.pfnIoReqGetActiveCount = drvvdIoReqGetActiveCount; 4318 4510 pThis->IMediaEx.pfnIoReqGetSuspendedCount = drvvdIoReqGetSuspendedCount; … … 4990 5182 if (!fDiscard) 4991 5183 { 4992 pThis->IMedia.pfnDiscard = NULL;5184 pThis->IMedia.pfnDiscard = NULL; 4993 5185 pThis->IMediaAsync.pfnStartDiscard = NULL; 5186 pThis->IMediaEx.pfnIoReqDiscard = NULL; 4994 5187 } 4995 5188 … … 5112 5305 if (cbStr > 0) 5113 5306 { 5307 bool fMediaEx = strcmp(pcszController, "nvme") == 0 ? true : false; 5114 5308 rc = PDMDrvHlpBlkCacheRetain(pDrvIns, &pThis->pBlkCache, 5115 drvvdBlkCacheXferComplete, 5309 fMediaEx ? drvvdBlkCacheXferCompleteIoReq 5310 : drvvdBlkCacheXferComplete, 5116 5311 drvvdBlkCacheXferEnqueue, 5117 5312 drvvdBlkCacheXferEnqueueDiscard, … … 5138 5333 /* 5139 5334 * Register a load-done callback so we can undo TempReadOnly config before 5140 * we get to drvvdResume. Auto amtically deregistered upon destruction.5335 * we get to drvvdResume. Automatically deregistered upon destruction. 5141 5336 */ 5142 5337 if (RT_SUCCESS(rc))
Note:
See TracChangeset
for help on using the changeset viewer.