- Timestamp:
- Sep 26, 2016 11:40:57 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/pdmstorageifs.h
r63997 r64002 473 473 474 474 475 /** Pointer to an asynchronous notification interface. */476 typedef struct PDMIMEDIAASYNCPORT *PPDMIMEDIAASYNCPORT;477 /**478 * Asynchronous version of the media interface (up).479 * Pair with PDMIMEDIAASYNC.480 */481 typedef struct PDMIMEDIAASYNCPORT482 {483 /**484 * Notify completion of a task.485 *486 * @returns VBox status code.487 * @param pInterface Pointer to the interface structure containing the called function pointer.488 * @param pvUser The user argument given in pfnStartWrite.489 * @param rcReq IPRT Status code of the completed request.490 * @thread Any thread.491 */492 DECLR3CALLBACKMEMBER(int, pfnTransferCompleteNotify, (PPDMIMEDIAASYNCPORT pInterface, void *pvUser, int rcReq));493 } PDMIMEDIAASYNCPORT;494 /** PDMIMEDIAASYNCPORT interface ID. */495 #define PDMIMEDIAASYNCPORT_IID "22d38853-901f-4a71-9670-4d9da6e82317"496 497 498 /** Pointer to an asynchronous media interface. */499 typedef struct PDMIMEDIAASYNC *PPDMIMEDIAASYNC;500 /**501 * Asynchronous version of PDMIMEDIA (down).502 * Pair with PDMIMEDIAASYNCPORT.503 */504 typedef struct PDMIMEDIAASYNC505 {506 /**507 * Start reading task.508 *509 * @returns VBox status code.510 * @param pInterface Pointer to the interface structure containing the called function pointer.511 * @param off Offset to start reading from. Must be aligned to a sector boundary.512 * @param paSegs Pointer to the S/G segment array.513 * @param cSegs Number of entries in the array.514 * @param cbRead Number of bytes to read. Must be aligned to a sector boundary.515 * @param pvUser User data.516 * @thread Any thread.517 */518 DECLR3CALLBACKMEMBER(int, pfnStartRead,(PPDMIMEDIAASYNC pInterface, uint64_t off, PCRTSGSEG paSegs, unsigned cSegs, size_t cbRead, void *pvUser));519 520 /**521 * Start writing task.522 *523 * @returns VBox status code.524 * @param pInterface Pointer to the interface structure containing the called function pointer.525 * @param off Offset to start writing at. Must be aligned to a sector boundary.526 * @param paSegs Pointer to the S/G segment array.527 * @param cSegs Number of entries in the array.528 * @param cbWrite Number of bytes to write. Must be aligned to a sector boundary.529 * @param pvUser User data.530 * @thread Any thread.531 */532 DECLR3CALLBACKMEMBER(int, pfnStartWrite,(PPDMIMEDIAASYNC pInterface, uint64_t off, PCRTSGSEG paSegs, unsigned cSegs, size_t cbWrite, void *pvUser));533 534 /**535 * Flush everything to disk.536 *537 * @returns VBox status code.538 * @param pInterface Pointer to the interface structure containing the called function pointer.539 * @param pvUser User argument which is returned in completion callback.540 * @thread Any thread.541 */542 DECLR3CALLBACKMEMBER(int, pfnStartFlush,(PPDMIMEDIAASYNC pInterface, void *pvUser));543 544 /**545 * Discards the given range.546 *547 * @returns VBox status code.548 * @param pInterface Pointer to the interface structure containing the called function pointer.549 * @param paRanges Array of ranges to discard.550 * @param cRanges Number of entries in the array.551 * @param pvUser User argument which is returned in completion callback.552 * @thread Any thread.553 */554 DECLR3CALLBACKMEMBER(int, pfnStartDiscard,(PPDMIMEDIAASYNC pInterface, PCRTRANGE paRanges, unsigned cRanges, void *pvUser));555 556 } PDMIMEDIAASYNC;557 /** PDMIMEDIAASYNC interface ID. */558 #define PDMIMEDIAASYNC_IID "4be209d3-ccb5-4297-82fe-7d8018bc6ab4"559 560 561 475 /** 562 476 * Opaque I/O request handle. -
trunk/src/VBox/Devices/Samples/DrvStorageFilter.cpp
r63886 r64002 41 41 PDMIMEDIA IMedia; 42 42 PDMIMEDIAPORT IMediaPort; 43 PDMIMEDIA ASYNC IMediaAsync;44 PDMIMEDIA ASYNCPORT IMediaAsyncPort;43 PDMIMEDIAEX IMediaEx; 44 PDMIMEDIAEXPORT IMediaExPort; 45 45 /** @} */ 46 46 … … 48 48 * @{ */ 49 49 PPDMIMEDIA pIMediaBelow; 50 PPDMIMEDIA ASYNC pIMediaAsyncBelow;50 PPDMIMEDIAEX pIMediaExBelow; 51 51 /** @} */ 52 52 … … 54 54 * @{ */ 55 55 PPDMIMEDIAPORT pIMediaPortAbove; 56 PPDMIMEDIA ASYNCPORT pIMediaAsyncPortAbove;56 PPDMIMEDIAEXPORT pIMediaExPortAbove; 57 57 /** @} */ 58 58 … … 69 69 /* 70 70 * 71 * IMediaAsyncPort Implementation. 72 * 73 */ 74 75 /** @interface_method_impl{PDMIMEDIAASYNCPORT,pfnTransferCompleteNotify} */ 76 static DECLCALLBACK(int) 77 drvStorageFltIMediaAsyncPort_TransferCompleteNotify(PPDMIMEDIAASYNCPORT pInterface, void *pvUser, int rcReq) 78 { 79 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaAsyncPort); 80 int rc = pThis->pIMediaAsyncPortAbove->pfnTransferCompleteNotify(pThis->pIMediaAsyncPortAbove, pvUser, rcReq); 81 return rc; 82 } 83 84 85 /* 86 * 87 * IMediaAsync Implementation. 88 * 89 */ 90 91 /** @interface_method_impl{PDMIMEDIAASYNC,pfnStartRead} */ 92 static DECLCALLBACK(int) drvStorageFltIMediaAsync_StartRead(PPDMIMEDIAASYNC pInterface, uint64_t off, 93 PCRTSGSEG paSegs, unsigned cSegs, size_t cbRead, void *pvUser) 94 { 95 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaAsync); 96 int rc = pThis->pIMediaAsyncBelow->pfnStartRead(pThis->pIMediaAsyncBelow, off, paSegs, cSegs, cbRead, pvUser); 97 return rc; 98 } 99 100 /** @interface_method_impl{PDMIMEDIAASYNC,pfnStartWrite} */ 101 static DECLCALLBACK(int) drvStorageFltIMediaAsync_StartWrite(PPDMIMEDIAASYNC pInterface, uint64_t off, 102 PCRTSGSEG paSegs, unsigned cSegs, size_t cbWrite, void *pvUser) 103 { 104 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaAsync); 105 int rc = pThis->pIMediaAsyncBelow->pfnStartWrite(pThis->pIMediaAsyncBelow, off, paSegs, cSegs, cbWrite, pvUser); 106 return rc; 107 } 108 109 /** @interface_method_impl{PDMIMEDIAASYNC,pfnStartFlush} */ 110 static DECLCALLBACK(int) drvStorageFltIMediaAsync_StartFlush(PPDMIMEDIAASYNC pInterface, void *pvUser) 111 { 112 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaAsync); 113 int rc = pThis->pIMediaAsyncBelow->pfnStartFlush(pThis->pIMediaAsyncBelow, pvUser); 114 return rc; 115 } 116 117 118 /** @interface_method_impl{PDMIMEDIAASYNC,pfnStartDiscard} */ 119 static DECLCALLBACK(int) drvStorageFltIMediaAsync_StartDiscard(PPDMIMEDIAASYNC pInterface, PCRTRANGE paRanges, 120 unsigned cRanges, void *pvUser) 121 { 122 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaAsync); 123 int rc = pThis->pIMediaAsyncBelow->pfnStartDiscard(pThis->pIMediaAsyncBelow, paRanges, cRanges, pvUser); 124 return rc; 125 } 126 127 128 /* 129 * 130 * IMedia Implementation. 71 * IMediaPort Implementation. 131 72 * 132 73 */ … … 242 183 int rc = pThis->pIMediaBelow->pfnDiscard(pThis->pIMediaBelow, paRanges, cRanges); 243 184 return rc; 185 } 186 187 188 /* 189 * 190 * IMediaExPort Implementation. 191 * 192 */ 193 194 /** @interface_method_impl{PDMIMEDIAEXPORT,pfnIoReqCompleteNotify} */ 195 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqCompleteNotify(PPDMIMEDIAEXPORT pInterface, PDMMEDIAEXIOREQ hIoReq, 196 void *pvIoReqAlloc, int rcReq) 197 { 198 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaExPort); 199 return pThis->pIMediaExPortAbove->pfnIoReqCompleteNotify(pThis->pIMediaExPortAbove, hIoReq, pvIoReqAlloc, rcReq); 200 } 201 202 203 /** @interface_method_impl{PDMIMEDIAEXPORT,pfnIoReqCopyFromBuf} */ 204 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqCopyFromBuf(PPDMIMEDIAEXPORT pInterface, PDMMEDIAEXIOREQ hIoReq, 205 void *pvIoReqAlloc, uint32_t offDst, PRTSGBUF pSgBuf, 206 size_t cbCopy) 207 { 208 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaExPort); 209 return pThis->pIMediaExPortAbove->pfnIoReqCopyFromBuf(pThis->pIMediaExPortAbove, hIoReq, pvIoReqAlloc, 210 offDst, pSgBuf, cbCopy); 211 } 212 213 /** @interface_method_impl{PDMIMEDIAEXPORT,pfnIoReqCopyToBuf} */ 214 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqCopyToBuf(PPDMIMEDIAEXPORT pInterface, PDMMEDIAEXIOREQ hIoReq, 215 void *pvIoReqAlloc, uint32_t offSrc, PRTSGBUF pSgBuf, 216 size_t cbCopy) 217 { 218 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaExPort); 219 return pThis->pIMediaExPortAbove->pfnIoReqCopyToBuf(pThis->pIMediaExPortAbove, hIoReq, pvIoReqAlloc, 220 offSrc, pSgBuf, cbCopy); 221 } 222 223 /** @interface_method_impl{PDMIMEDIAEXPORT,pfnIoReqQueryDiscardRanges} */ 224 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqQueryDiscardRanges(PPDMIMEDIAEXPORT pInterface, PDMMEDIAEXIOREQ hIoReq, 225 void *pvIoReqAlloc, uint32_t idxRangeStart, 226 uint32_t cRanges, PRTRANGE paRanges, 227 uint32_t *pcRanges) 228 { 229 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaExPort); 230 return pThis->pIMediaExPortAbove->pfnIoReqQueryDiscardRanges(pThis->pIMediaExPortAbove, hIoReq, pvIoReqAlloc, 231 idxRangeStart, cRanges, paRanges, pcRanges); 232 } 233 234 /** @interface_method_impl{PDMIMEDIAEXPORT,pfnIoReqStateChanged} */ 235 static DECLCALLBACK(void) drvStorageFltIMedia_IoReqStateChanged(PPDMIMEDIAEXPORT pInterface, PDMMEDIAEXIOREQ hIoReq, 236 void *pvIoReqAlloc, PDMMEDIAEXIOREQSTATE enmState) 237 { 238 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaExPort); 239 return pThis->pIMediaExPortAbove->pfnIoReqStateChanged(pThis->pIMediaExPortAbove, hIoReq, pvIoReqAlloc, enmState); 240 } 241 242 243 /* 244 * 245 * IMediaEx Implementation. 246 * 247 */ 248 249 /** @interface_method_impl{PDMIMEDIAEX,pfnQueryFeatures} */ 250 static DECLCALLBACK(int) drvStorageFltIMedia_QueryFeatures(PPDMIMEDIAEX pInterface, uint32_t *pfFeatures) 251 { 252 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 253 254 int rc = pThis->pIMediaExBelow->pfnQueryFeatures(pThis->pIMediaExBelow, pfFeatures); 255 if (RT_SUCCESS(rc) && !pThis->fAsyncIOSupported) 256 *pfFeatures &= ~PDMIMEDIAEX_FEATURE_F_ASYNC; 257 258 return rc; 259 } 260 261 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqAllocSizeSet} */ 262 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqAllocSizeSet(PPDMIMEDIAEX pInterface, size_t cbIoReqAlloc) 263 { 264 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 265 return pThis->pIMediaExBelow->pfnIoReqAllocSizeSet(pThis->pIMediaExBelow, cbIoReqAlloc); 266 } 267 268 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqAlloc} */ 269 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqAlloc(PPDMIMEDIAEX pInterface, PPDMMEDIAEXIOREQ phIoReq, void **ppvIoReqAlloc, 270 PDMMEDIAEXIOREQID uIoReqId, uint32_t fFlags) 271 { 272 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 273 274 if (!pThis->fAsyncIOSupported) 275 fFlags |= PDMIMEDIAEX_F_SYNC; 276 return pThis->pIMediaExBelow->pfnIoReqAlloc(pThis->pIMediaExBelow, phIoReq, ppvIoReqAlloc, uIoReqId, fFlags); 277 } 278 279 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqFree} */ 280 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqFree(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq) 281 { 282 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 283 return pThis->pIMediaExBelow->pfnIoReqFree(pThis->pIMediaExBelow, hIoReq); 284 } 285 286 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqQueryResidual} */ 287 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqQueryResidual(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, size_t *pcbResidual) 288 { 289 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 290 return pThis->pIMediaExBelow->pfnIoReqQueryResidual(pThis->pIMediaExBelow, hIoReq, pcbResidual); 291 } 292 293 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqCancelAll} */ 294 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqCancelAll(PPDMIMEDIAEX pInterface) 295 { 296 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 297 return pThis->pIMediaExBelow->pfnIoReqCancelAll(pThis->pIMediaExBelow); 298 } 299 300 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqCancel} */ 301 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqCancel(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQID uIoReqId) 302 { 303 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 304 return pThis->pIMediaExBelow->pfnIoReqCancel(pThis->pIMediaExBelow, uIoReqId); 305 } 306 307 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqRead} */ 308 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqRead(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, uint64_t off, size_t cbRead) 309 { 310 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 311 return pThis->pIMediaExBelow->pfnIoReqRead(pThis->pIMediaExBelow, hIoReq, off, cbRead); 312 } 313 314 /** 315 * @interface_method_impl{PDMIMEDIAEX,pfnIoReqWrite} 316 */ 317 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqWrite(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, uint64_t off, size_t cbWrite) 318 { 319 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 320 return pThis->pIMediaExBelow->pfnIoReqWrite(pThis->pIMediaExBelow, hIoReq, off, cbWrite); 321 } 322 323 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqFlush} */ 324 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqFlush(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq) 325 { 326 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 327 return pThis->pIMediaExBelow->pfnIoReqFlush(pThis->pIMediaExBelow, hIoReq); 328 } 329 330 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqDiscard} */ 331 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqDiscard(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, unsigned cRangesMax) 332 { 333 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 334 return pThis->pIMediaExBelow->pfnIoReqDiscard(pThis->pIMediaExBelow, hIoReq, cRangesMax); 335 } 336 337 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqSendScsiCmd} */ 338 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqSendScsiCmd(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, uint32_t uLun, 339 const uint8_t *pbCdb, size_t cbCdb, PDMMEDIAEXIOREQSCSITXDIR enmTxDir, 340 size_t cbBuf, uint8_t *pabSense, size_t cbSense, uint32_t cTimeoutMillies) 341 { 342 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 343 return pThis->pIMediaExBelow->pfnIoReqSendScsiCmd(pThis->pIMediaExBelow, hIoReq, uLun, pbCdb, cbCdb, 344 enmTxDir, cbBuf, pabSense, cbSense, cTimeoutMillies); 345 } 346 347 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqGetActiveCount} */ 348 static DECLCALLBACK(uint32_t) drvStorageFltIMedia_IoReqGetActiveCount(PPDMIMEDIAEX pInterface) 349 { 350 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 351 return pThis->pIMediaExBelow->pfnIoReqGetActiveCount(pThis->pIMediaExBelow); 352 } 353 354 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqGetSuspendedCount} */ 355 static DECLCALLBACK(uint32_t) drvStorageFltIMedia_IoReqGetSuspendedCount(PPDMIMEDIAEX pInterface) 356 { 357 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 358 return pThis->pIMediaExBelow->pfnIoReqGetSuspendedCount(pThis->pIMediaExBelow); 359 } 360 361 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqQuerySuspendedFirst} */ 362 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqQuerySuspendedStart(PPDMIMEDIAEX pInterface, PPDMMEDIAEXIOREQ phIoReq, 363 void **ppvIoReqAlloc) 364 { 365 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 366 return pThis->pIMediaExBelow->pfnIoReqQuerySuspendedStart(pThis->pIMediaExBelow, phIoReq, ppvIoReqAlloc); 367 } 368 369 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqQuerySuspendedNext} */ 370 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqQuerySuspendedNext(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, 371 PPDMMEDIAEXIOREQ phIoReqNext, void **ppvIoReqAllocNext) 372 { 373 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 374 return pThis->pIMediaExBelow->pfnIoReqQuerySuspendedNext(pThis->pIMediaExBelow, hIoReq, phIoReqNext, ppvIoReqAllocNext); 375 } 376 377 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqSuspendedSave} */ 378 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqSuspendedSave(PPDMIMEDIAEX pInterface, PSSMHANDLE pSSM, PDMMEDIAEXIOREQ hIoReq) 379 { 380 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 381 return pThis->pIMediaExBelow->pfnIoReqSuspendedSave(pThis->pIMediaExBelow, pSSM, hIoReq); 382 } 383 384 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqSuspendedLoad} */ 385 static DECLCALLBACK(int) drvStorageFltIMedia_IoReqSuspendedLoad(PPDMIMEDIAEX pInterface, PSSMHANDLE pSSM, PDMMEDIAEXIOREQ hIoReq) 386 { 387 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx); 388 return pThis->pIMediaExBelow->pfnIoReqSuspendedLoad(pThis->pIMediaExBelow, pSSM, hIoReq); 244 389 } 245 390 … … 262 407 if (pThis->pIMediaPortAbove) 263 408 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAPORT, &pThis->IMediaPort); 264 265 if (pThis->fAsyncIOSupported && pThis->pIMediaAsyncBelow)266 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAASYNC, &pThis->IMediaAsync);267 if (pThis->fAsyncIOSupported && pThis->pIMediaAsyncPortAbove)268 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAASYNCPORT, &pThis->IMediaAsyncPort); 409 if (pThis->pIMediaExBelow) 410 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAEX, &pThis->IMediaEx); 411 if (pThis->pIMediaExPortAbove) 412 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAEXPORT, &pThis->IMediaExPort); 413 269 414 return NULL; 270 415 } … … 307 452 pThis->IMedia.pfnDiscard = drvStorageFltIMedia_Discard; 308 453 454 pThis->IMediaEx.pfnQueryFeatures = drvStorageFltIMedia_QueryFeatures; 455 pThis->IMediaEx.pfnIoReqAllocSizeSet = drvStorageFltIMedia_IoReqAllocSizeSet; 456 pThis->IMediaEx.pfnIoReqAlloc = drvStorageFltIMedia_IoReqAlloc; 457 pThis->IMediaEx.pfnIoReqFree = drvStorageFltIMedia_IoReqFree; 458 pThis->IMediaEx.pfnIoReqQueryResidual = drvStorageFltIMedia_IoReqQueryResidual; 459 pThis->IMediaEx.pfnIoReqCancelAll = drvStorageFltIMedia_IoReqCancelAll; 460 pThis->IMediaEx.pfnIoReqCancel = drvStorageFltIMedia_IoReqCancel; 461 pThis->IMediaEx.pfnIoReqRead = drvStorageFltIMedia_IoReqRead; 462 pThis->IMediaEx.pfnIoReqWrite = drvStorageFltIMedia_IoReqWrite; 463 pThis->IMediaEx.pfnIoReqFlush = drvStorageFltIMedia_IoReqFlush; 464 pThis->IMediaEx.pfnIoReqDiscard = drvStorageFltIMedia_IoReqDiscard; 465 pThis->IMediaEx.pfnIoReqSendScsiCmd = drvStorageFltIMedia_IoReqSendScsiCmd; 466 pThis->IMediaEx.pfnIoReqGetActiveCount = drvStorageFltIMedia_IoReqGetActiveCount; 467 pThis->IMediaEx.pfnIoReqGetSuspendedCount = drvStorageFltIMedia_IoReqGetSuspendedCount; 468 pThis->IMediaEx.pfnIoReqQuerySuspendedStart = drvStorageFltIMedia_IoReqQuerySuspendedStart; 469 pThis->IMediaEx.pfnIoReqQuerySuspendedNext = drvStorageFltIMedia_IoReqQuerySuspendedNext; 470 pThis->IMediaEx.pfnIoReqSuspendedSave = drvStorageFltIMedia_IoReqSuspendedSave; 471 pThis->IMediaEx.pfnIoReqSuspendedLoad = drvStorageFltIMedia_IoReqSuspendedLoad; 472 309 473 pThis->IMediaPort.pfnQueryDeviceLocation = drvStorageFltIMediaPort_QueryDeviceLocation; 310 474 311 pThis->IMediaAsync.pfnStartRead = drvStorageFltIMediaAsync_StartRead; 312 pThis->IMediaAsync.pfnStartWrite = drvStorageFltIMediaAsync_StartWrite; 313 pThis->IMediaAsync.pfnStartFlush = drvStorageFltIMediaAsync_StartFlush; 314 pThis->IMediaAsync.pfnStartDiscard = drvStorageFltIMediaAsync_StartDiscard; 315 316 pThis->IMediaAsyncPort.pfnTransferCompleteNotify = drvStorageFltIMediaAsyncPort_TransferCompleteNotify; 475 pThis->IMediaExPort.pfnIoReqCompleteNotify = drvStorageFltIMedia_IoReqCompleteNotify; 476 pThis->IMediaExPort.pfnIoReqCopyFromBuf = drvStorageFltIMedia_IoReqCopyFromBuf; 477 pThis->IMediaExPort.pfnIoReqCopyToBuf = drvStorageFltIMedia_IoReqCopyToBuf; 478 pThis->IMediaExPort.pfnIoReqQueryDiscardRanges = drvStorageFltIMedia_IoReqQueryDiscardRanges; 479 pThis->IMediaExPort.pfnIoReqStateChanged = drvStorageFltIMedia_IoReqStateChanged; 317 480 318 481 /* … … 327 490 * Query interfaces from the driver/device above us. 328 491 */ 329 pThis->pIMediaPortAbove 330 pThis->pIMedia AsyncPortAbove = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAASYNCPORT);492 pThis->pIMediaPortAbove = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAPORT); 493 pThis->pIMediaExPortAbove = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAEXPORT); 331 494 332 495 /* … … 337 500 AssertLogRelRCReturn(rc, rc); 338 501 339 pThis->pIMediaBelow 340 pThis->pIMedia AsyncBelow = PDMIBASE_QUERY_INTERFACE(pIBaseBelow, PDMIMEDIAASYNC);502 pThis->pIMediaBelow = PDMIBASE_QUERY_INTERFACE(pIBaseBelow, PDMIMEDIA); 503 pThis->pIMediaExBelow = PDMIBASE_QUERY_INTERFACE(pIBaseBelow, PDMIMEDIAEX); 341 504 342 505 AssertLogRelReturn(pThis->pIMediaBelow, VERR_PDM_MISSING_INTERFACE_BELOW); … … 344 507 if (!pThis->pIMediaBelow->pfnDiscard) 345 508 pThis->IMedia.pfnDiscard = NULL; 346 if (!pThis->pIMediaAsyncBelow || !pThis->pIMediaAsyncBelow->pfnStartDiscard)347 pThis->IMediaAsync.pfnStartDiscard = NULL;348 509 349 510 return VINF_SUCCESS; -
trunk/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp
r63997 r64002 156 156 PDMIMEDIAPORT IMediaPort; 157 157 158 /** Pointer to the media async driver below us.159 * This is NULL if the media is not mounted. */160 PPDMIMEDIAASYNC pDrvMediaAsync;161 /** Our media async interface */162 PDMIMEDIAASYNC IMediaAsync;163 164 /** The async media port interface above. */165 PPDMIMEDIAASYNCPORT pDrvMediaAsyncPort;166 /** Our media async port interface */167 PDMIMEDIAASYNCPORT IMediaAsyncPort;168 169 158 /** The extended media port interface above. */ 170 159 PPDMIMEDIAEXPORT pDrvMediaExPort; … … 225 214 226 215 227 /**228 * Allocate a new I/O request.229 *230 * @returns New I/O request.231 * @param enmTxDir Transfer direction.232 * @param off Start offset.233 * @param paSeg Segment array.234 * @param cSeg Number of segments.235 * @param cbTransfer Number of bytes to transfer.236 * @param pvUser User argument.237 */238 static PDRVDISKAIOREQ drvdiskintIoReqAlloc(DRVDISKAIOTXDIR enmTxDir, uint64_t off, PCRTSGSEG paSeg,239 unsigned cSeg, size_t cbTransfer, void *pvUser)240 {241 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)RTMemAlloc(sizeof(DRVDISKAIOREQ));242 243 if (RT_LIKELY(pIoReq))244 {245 pIoReq->enmTxDir = enmTxDir;246 pIoReq->off = off;247 pIoReq->cbTransfer = cbTransfer;248 pIoReq->paSeg = paSeg;249 pIoReq->cSeg = cSeg;250 pIoReq->pvUser = pvUser;251 pIoReq->iSlot = 0;252 pIoReq->tsStart = RTTimeSystemMilliTS();253 pIoReq->tsComplete = 0;254 pIoReq->hIoLogEntry = NULL;255 }256 257 return pIoReq;258 }259 260 216 static void drvdiskintIoReqCheckForDoubleCompletion(PDRVDISKINTEGRITY pThis, PDRVDISKAIOREQ pIoReq, 261 217 bool fMediaEx) … … 285 241 pThis->papIoReq[pThis->iEntry] = NULL; 286 242 } 287 }288 289 /**290 * Free a async I/O request.291 *292 * @returns nothing.293 * @param pThis Disk driver.294 * @param pIoReq The I/O request to free.295 */296 static void drvdiskintReqFree(PDRVDISKINTEGRITY pThis, PDRVDISKAIOREQ pIoReq)297 {298 if (pThis->fCheckDoubleCompletion)299 drvdiskintIoReqCheckForDoubleCompletion(pThis, pIoReq, false /* fMediaEx */);300 else301 RTMemFree(pIoReq);302 243 } 303 244 … … 775 716 /** Makes a PDRVDISKINTEGRITY out of a PPDMIMEDIA. */ 776 717 #define PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface) ( (PDRVDISKINTEGRITY)((uintptr_t)pInterface - RT_OFFSETOF(DRVDISKINTEGRITY, IMedia)) ) 777 /** Makes a PDRVDISKINTEGRITY out of a PPDMIMEDIAASYNC. */778 #define PDMIMEDIAASYNC_2_DRVDISKINTEGRITY(pInterface) ( (PDRVDISKINTEGRITY)((uintptr_t)pInterface - RT_OFFSETOF(DRVDISKINTEGRITY, IMediaAsync)) )779 718 780 719 … … 886 825 } 887 826 888 static DECLCALLBACK(int) drvdiskintStartRead(PPDMIMEDIAASYNC pInterface, uint64_t uOffset, 889 PCRTSGSEG paSeg, unsigned cSeg, 890 size_t cbRead, void *pvUser) 891 { 892 LogFlow(("%s: uOffset=%llu paSeg=%#p cSeg=%u cbRead=%d pvUser=%#p\n", __FUNCTION__, 893 uOffset, paSeg, cSeg, cbRead, pvUser)); 894 PDRVDISKINTEGRITY pThis = PDMIMEDIAASYNC_2_DRVDISKINTEGRITY(pInterface); 895 PDRVDISKAIOREQ pIoReq = drvdiskintIoReqAlloc(DRVDISKAIOTXDIR_READ, uOffset, paSeg, cSeg, cbRead, pvUser); 896 AssertPtr(pIoReq); 897 898 if (pThis->fTraceRequests) 899 drvdiskintIoReqAdd(pThis, pIoReq); 900 901 if (pThis->hIoLogger) 902 { 903 int rc2 = VDDbgIoLogStart(pThis->hIoLogger, true, VDDBGIOLOGREQ_READ, uOffset, 904 cbRead, NULL, &pIoReq->hIoLogEntry); 905 AssertRC(rc2); 906 } 907 908 int rc = pThis->pDrvMediaAsync->pfnStartRead(pThis->pDrvMediaAsync, uOffset, paSeg, cSeg, 909 cbRead, pIoReq); 910 if (rc == VINF_VD_ASYNC_IO_FINISHED) 911 { 912 /* Verify the read now. */ 913 if (pThis->fCheckConsistency) 914 { 915 int rc2 = drvdiskintReadVerify(pThis, paSeg, cSeg, uOffset, cbRead); 916 AssertRC(rc2); 917 } 918 919 if (pThis->hIoLogger) 920 { 921 RTSGBUF SgBuf; 922 923 RTSgBufInit(&SgBuf, paSeg, cSeg); 924 925 int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, pIoReq->hIoLogEntry, VINF_SUCCESS, &SgBuf); 926 AssertRC(rc2); 927 } 928 929 if (pThis->fTraceRequests) 930 drvdiskintIoReqRemove(pThis, pIoReq); 931 RTMemFree(pIoReq); 932 } 933 else if (RT_FAILURE(rc) && rc != VERR_VD_ASYNC_IO_IN_PROGRESS) 934 RTMemFree(pIoReq); 935 936 LogFlow(("%s: returns %Rrc\n", __FUNCTION__, rc)); 937 return rc; 938 } 939 940 static DECLCALLBACK(int) drvdiskintStartWrite(PPDMIMEDIAASYNC pInterface, uint64_t uOffset, 941 PCRTSGSEG paSeg, unsigned cSeg, 942 size_t cbWrite, void *pvUser) 943 { 944 LogFlow(("%s: uOffset=%#llx paSeg=%#p cSeg=%u cbWrite=%d pvUser=%#p\n", __FUNCTION__, 945 uOffset, paSeg, cSeg, cbWrite, pvUser)); 946 PDRVDISKINTEGRITY pThis = PDMIMEDIAASYNC_2_DRVDISKINTEGRITY(pInterface); 947 PDRVDISKAIOREQ pIoReq = drvdiskintIoReqAlloc(DRVDISKAIOTXDIR_WRITE, uOffset, paSeg, cSeg, cbWrite, pvUser); 948 AssertPtr(pIoReq); 949 950 if (pThis->fTraceRequests) 951 drvdiskintIoReqAdd(pThis, pIoReq); 952 953 if (pThis->hIoLogger) 954 { 955 RTSGBUF SgBuf; 956 957 RTSgBufInit(&SgBuf, paSeg, cSeg); 958 959 int rc2 = VDDbgIoLogStart(pThis->hIoLogger, true, VDDBGIOLOGREQ_WRITE, uOffset, 960 cbWrite, &SgBuf, &pIoReq->hIoLogEntry); 961 AssertRC(rc2); 962 } 963 964 if (pThis->fRecordWriteBeforeCompletion) 965 { 966 int rc2 = drvdiskintWriteRecord(pThis, paSeg, cSeg, uOffset, cbWrite); 967 AssertRC(rc2); 968 } 969 970 int rc = pThis->pDrvMediaAsync->pfnStartWrite(pThis->pDrvMediaAsync, uOffset, paSeg, cSeg, 971 cbWrite, pIoReq); 972 if (rc == VINF_VD_ASYNC_IO_FINISHED) 973 { 974 /* Record the write. */ 975 if ( pThis->fCheckConsistency 976 && !pThis->fRecordWriteBeforeCompletion) 977 { 978 int rc2 = drvdiskintWriteRecord(pThis, paSeg, cSeg, uOffset, cbWrite); 979 AssertRC(rc2); 980 } 981 982 if (pThis->hIoLogger) 983 { 984 int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, pIoReq->hIoLogEntry, VINF_SUCCESS, NULL); 985 AssertRC(rc2); 986 } 987 988 if (pThis->fTraceRequests) 989 drvdiskintIoReqRemove(pThis, pIoReq); 990 991 RTMemFree(pIoReq); 992 } 993 else if (RT_FAILURE(rc) && rc != VERR_VD_ASYNC_IO_IN_PROGRESS) 994 RTMemFree(pIoReq); 995 996 LogFlow(("%s: returns %Rrc\n", __FUNCTION__, rc)); 997 return rc; 998 } 999 1000 /** @interface_method_impl{PDMIMEDIAASYNC,pfnStartFlush} */ 1001 static DECLCALLBACK(int) drvdiskintStartFlush(PPDMIMEDIAASYNC pInterface, void *pvUser) 1002 { 1003 int rc = VINF_SUCCESS; 1004 PDRVDISKINTEGRITY pThis = PDMIMEDIAASYNC_2_DRVDISKINTEGRITY(pInterface); 1005 PDRVDISKAIOREQ pIoReq = drvdiskintIoReqAlloc(DRVDISKAIOTXDIR_FLUSH, 0, NULL, 0, 0, pvUser); 1006 AssertPtr(pIoReq); 1007 1008 if (pThis->fTraceRequests) 1009 drvdiskintIoReqAdd(pThis, pIoReq); 1010 1011 if (pThis->hIoLogger) 1012 { 1013 rc = VDDbgIoLogStart(pThis->hIoLogger, true, VDDBGIOLOGREQ_FLUSH, 0, 1014 0, NULL, &pIoReq->hIoLogEntry); 1015 AssertRC(rc); 1016 } 1017 1018 rc = pThis->pDrvMediaAsync->pfnStartFlush(pThis->pDrvMediaAsync, pIoReq); 1019 1020 if (rc == VINF_VD_ASYNC_IO_FINISHED) 1021 { 1022 if (pThis->hIoLogger) 1023 { 1024 int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, pIoReq->hIoLogEntry, VINF_SUCCESS, NULL); 1025 AssertRC(rc2); 1026 } 1027 1028 RTMemFree(pIoReq); 1029 } 1030 else if (RT_FAILURE(rc) && rc != VERR_VD_ASYNC_IO_IN_PROGRESS) 1031 RTMemFree(pIoReq); 1032 1033 LogFlow(("%s: returns %Rrc\n", __FUNCTION__, rc)); 1034 return rc; 1035 } 1036 1037 /** @interface_method_impl{PDMIMEDIAASYNC,pfnStartDiscard} */ 1038 static DECLCALLBACK(int) drvdiskintStartDiscard(PPDMIMEDIAASYNC pInterface, PCRTRANGE paRanges, unsigned cRanges, void *pvUser) 827 /** @interface_method_impl{PDMIMEDIA,pfnFlush} */ 828 static DECLCALLBACK(int) drvdiskintFlush(PPDMIMEDIA pInterface) 1039 829 { 1040 830 int rc = VINF_SUCCESS; 1041 831 VDIOLOGENT hIoLogEntry; 1042 832 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface); 1043 PDRVDISKAIOREQ pIoReq = drvdiskintIoReqAlloc(DRVDISKAIOTXDIR_DISCARD, 0, NULL, 0, 0, pvUser);1044 AssertPtr(pIoReq);1045 1046 pIoReq->paRanges = paRanges;1047 pIoReq->cRanges = cRanges;1048 833 1049 834 if (pThis->hIoLogger) 1050 835 { 1051 rc = VDDbgIoLogStartDiscard(pThis->hIoLogger, true, paRanges, cRanges, &hIoLogEntry); 836 rc = VDDbgIoLogStart(pThis->hIoLogger, false, VDDBGIOLOGREQ_FLUSH, 0, 837 0, NULL, &hIoLogEntry); 1052 838 AssertRC(rc); 1053 839 } 1054 840 1055 rc = pThis->pDrvMediaAsync->pfnStartDiscard(pThis->pDrvMediaAsync, paRanges, cRanges, pIoReq); 1056 1057 if (rc == VINF_VD_ASYNC_IO_FINISHED) 1058 { 1059 if (pThis->hIoLogger) 1060 { 1061 int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, pIoReq->hIoLogEntry, VINF_SUCCESS, NULL); 1062 AssertRC(rc2); 1063 } 1064 1065 RTMemFree(pIoReq); 1066 } 1067 else if (RT_FAILURE(rc) && rc != VERR_VD_ASYNC_IO_IN_PROGRESS) 1068 RTMemFree(pIoReq); 841 rc = pThis->pDrvMedia->pfnFlush(pThis->pDrvMedia); 842 843 if (pThis->hIoLogger) 844 { 845 int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, hIoLogEntry, rc, NULL); 846 AssertRC(rc2); 847 } 1069 848 1070 849 return rc; 1071 850 } 1072 851 1073 /** @interface_method_impl{PDMIMEDIA,pfnFlush} */ 1074 static DECLCALLBACK(int) drvdiskintFlush(PPDMIMEDIA pInterface) 852 /** @interface_method_impl{PDMIMEDIA,pfnGetSize} */ 853 static DECLCALLBACK(uint64_t) drvdiskintGetSize(PPDMIMEDIA pInterface) 854 { 855 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface); 856 return pThis->pDrvMedia->pfnGetSize(pThis->pDrvMedia); 857 } 858 859 /** @interface_method_impl{PDMIMEDIA,pfnIsReadOnly} */ 860 static DECLCALLBACK(bool) drvdiskintIsReadOnly(PPDMIMEDIA pInterface) 861 { 862 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface); 863 return pThis->pDrvMedia->pfnIsReadOnly(pThis->pDrvMedia); 864 } 865 866 /** @interface_method_impl{PDMIMEDIA,pfnBiosIsVisible} */ 867 static DECLCALLBACK(bool) drvdiskintBiosIsVisible(PPDMIMEDIA pInterface) 868 { 869 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface); 870 return pThis->pDrvMedia->pfnBiosIsVisible(pInterface); 871 } 872 873 /** @interface_method_impl{PDMIMEDIA,pfnGetType} */ 874 static DECLCALLBACK(PDMMEDIATYPE) drvdiskintGetType(PPDMIMEDIA pInterface) 875 { 876 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface); 877 return pThis->pDrvMedia->pfnGetType(pThis->pDrvMedia); 878 } 879 880 /** @interface_method_impl{PDMIMEDIA,pfnBiosGetPCHSGeometry} */ 881 static DECLCALLBACK(int) drvdiskintBiosGetPCHSGeometry(PPDMIMEDIA pInterface, 882 PPDMMEDIAGEOMETRY pPCHSGeometry) 883 { 884 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface); 885 return pThis->pDrvMedia->pfnBiosGetPCHSGeometry(pThis->pDrvMedia, pPCHSGeometry); 886 } 887 888 /** @interface_method_impl{PDMIMEDIA,pfnBiosSetPCHSGeometry} */ 889 static DECLCALLBACK(int) drvdiskintBiosSetPCHSGeometry(PPDMIMEDIA pInterface, 890 PCPDMMEDIAGEOMETRY pPCHSGeometry) 891 { 892 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface); 893 return pThis->pDrvMedia->pfnBiosSetPCHSGeometry(pThis->pDrvMedia, pPCHSGeometry); 894 } 895 896 /** @interface_method_impl{PDMIMEDIA,pfnBiosGetLCHSGeometry} */ 897 static DECLCALLBACK(int) drvdiskintBiosGetLCHSGeometry(PPDMIMEDIA pInterface, 898 PPDMMEDIAGEOMETRY pLCHSGeometry) 899 { 900 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface); 901 return pThis->pDrvMedia->pfnBiosGetLCHSGeometry(pThis->pDrvMedia, pLCHSGeometry); 902 } 903 904 /** @interface_method_impl{PDMIMEDIA,pfnBiosSetLCHSGeometry} */ 905 static DECLCALLBACK(int) drvdiskintBiosSetLCHSGeometry(PPDMIMEDIA pInterface, 906 PCPDMMEDIAGEOMETRY pLCHSGeometry) 907 { 908 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface); 909 return pThis->pDrvMedia->pfnBiosSetLCHSGeometry(pThis->pDrvMedia, pLCHSGeometry); 910 } 911 912 /** @interface_method_impl{PDMIMEDIA,pfnGetUuid} */ 913 static DECLCALLBACK(int) drvdiskintGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid) 914 { 915 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface); 916 return pThis->pDrvMedia->pfnGetUuid(pThis->pDrvMedia, pUuid); 917 } 918 919 /** @interface_method_impl{PDMIMEDIA,pfnGetSectorSize} */ 920 static DECLCALLBACK(uint32_t) drvdiskintGetSectorSize(PPDMIMEDIA pInterface) 921 { 922 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface); 923 return pThis->pDrvMedia->pfnGetSectorSize(pThis->pDrvMedia); 924 } 925 926 /** @interface_method_impl{PDMIMEDIA,pfnDiscard} */ 927 static DECLCALLBACK(int) drvdiskintDiscard(PPDMIMEDIA pInterface, PCRTRANGE paRanges, unsigned cRanges) 1075 928 { 1076 929 int rc = VINF_SUCCESS; … … 1080 933 if (pThis->hIoLogger) 1081 934 { 1082 rc = VDDbgIoLogStart(pThis->hIoLogger, false, VDDBGIOLOGREQ_FLUSH, 0,1083 0, NULL, &hIoLogEntry);1084 AssertRC(rc);1085 }1086 1087 rc = pThis->pDrvMedia->pfnFlush(pThis->pDrvMedia);1088 1089 if (pThis->hIoLogger)1090 {1091 int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, hIoLogEntry, rc, NULL);1092 AssertRC(rc2);1093 }1094 1095 return rc;1096 }1097 1098 /** @interface_method_impl{PDMIMEDIA,pfnGetSize} */1099 static DECLCALLBACK(uint64_t) drvdiskintGetSize(PPDMIMEDIA pInterface)1100 {1101 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);1102 return pThis->pDrvMedia->pfnGetSize(pThis->pDrvMedia);1103 }1104 1105 /** @interface_method_impl{PDMIMEDIA,pfnIsReadOnly} */1106 static DECLCALLBACK(bool) drvdiskintIsReadOnly(PPDMIMEDIA pInterface)1107 {1108 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);1109 return pThis->pDrvMedia->pfnIsReadOnly(pThis->pDrvMedia);1110 }1111 1112 /** @interface_method_impl{PDMIMEDIA,pfnBiosIsVisible} */1113 static DECLCALLBACK(bool) drvdiskintBiosIsVisible(PPDMIMEDIA pInterface)1114 {1115 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);1116 return pThis->pDrvMedia->pfnBiosIsVisible(pInterface);1117 }1118 1119 /** @interface_method_impl{PDMIMEDIA,pfnGetType} */1120 static DECLCALLBACK(PDMMEDIATYPE) drvdiskintGetType(PPDMIMEDIA pInterface)1121 {1122 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);1123 return pThis->pDrvMedia->pfnGetType(pThis->pDrvMedia);1124 }1125 1126 /** @interface_method_impl{PDMIMEDIA,pfnBiosGetPCHSGeometry} */1127 static DECLCALLBACK(int) drvdiskintBiosGetPCHSGeometry(PPDMIMEDIA pInterface,1128 PPDMMEDIAGEOMETRY pPCHSGeometry)1129 {1130 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);1131 return pThis->pDrvMedia->pfnBiosGetPCHSGeometry(pThis->pDrvMedia, pPCHSGeometry);1132 }1133 1134 /** @interface_method_impl{PDMIMEDIA,pfnBiosSetPCHSGeometry} */1135 static DECLCALLBACK(int) drvdiskintBiosSetPCHSGeometry(PPDMIMEDIA pInterface,1136 PCPDMMEDIAGEOMETRY pPCHSGeometry)1137 {1138 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);1139 return pThis->pDrvMedia->pfnBiosSetPCHSGeometry(pThis->pDrvMedia, pPCHSGeometry);1140 }1141 1142 /** @interface_method_impl{PDMIMEDIA,pfnBiosGetLCHSGeometry} */1143 static DECLCALLBACK(int) drvdiskintBiosGetLCHSGeometry(PPDMIMEDIA pInterface,1144 PPDMMEDIAGEOMETRY pLCHSGeometry)1145 {1146 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);1147 return pThis->pDrvMedia->pfnBiosGetLCHSGeometry(pThis->pDrvMedia, pLCHSGeometry);1148 }1149 1150 /** @interface_method_impl{PDMIMEDIA,pfnBiosSetLCHSGeometry} */1151 static DECLCALLBACK(int) drvdiskintBiosSetLCHSGeometry(PPDMIMEDIA pInterface,1152 PCPDMMEDIAGEOMETRY pLCHSGeometry)1153 {1154 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);1155 return pThis->pDrvMedia->pfnBiosSetLCHSGeometry(pThis->pDrvMedia, pLCHSGeometry);1156 }1157 1158 /** @interface_method_impl{PDMIMEDIA,pfnGetUuid} */1159 static DECLCALLBACK(int) drvdiskintGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)1160 {1161 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);1162 return pThis->pDrvMedia->pfnGetUuid(pThis->pDrvMedia, pUuid);1163 }1164 1165 /** @interface_method_impl{PDMIMEDIA,pfnGetSectorSize} */1166 static DECLCALLBACK(uint32_t) drvdiskintGetSectorSize(PPDMIMEDIA pInterface)1167 {1168 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);1169 return pThis->pDrvMedia->pfnGetSectorSize(pThis->pDrvMedia);1170 }1171 1172 /** @interface_method_impl{PDMIMEDIA,pfnDiscard} */1173 static DECLCALLBACK(int) drvdiskintDiscard(PPDMIMEDIA pInterface, PCRTRANGE paRanges, unsigned cRanges)1174 {1175 int rc = VINF_SUCCESS;1176 VDIOLOGENT hIoLogEntry;1177 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);1178 1179 if (pThis->hIoLogger)1180 {1181 935 rc = VDDbgIoLogStartDiscard(pThis->hIoLogger, false, paRanges, cRanges, &hIoLogEntry); 1182 936 AssertRC(rc); … … 1223 977 1224 978 return pThis->pDrvMedia->pfnReadPcBios(pThis->pDrvMedia, off, pvBuf, cbRead); 1225 }1226 1227 /* -=-=-=-=- IMediaAsyncPort -=-=-=-=- */1228 1229 /** Makes a PDRVBLOCKASYNC out of a PPDMIMEDIAASYNCPORT. */1230 #define PDMIMEDIAASYNCPORT_2_DRVDISKINTEGRITY(pInterface) ( (PDRVDISKINTEGRITY((uintptr_t)pInterface - RT_OFFSETOF(DRVDISKINTEGRITY, IMediaAsyncPort))) )1231 1232 static DECLCALLBACK(int) drvdiskintAsyncTransferCompleteNotify(PPDMIMEDIAASYNCPORT pInterface, void *pvUser, int rcReq)1233 {1234 PDRVDISKINTEGRITY pThis = PDMIMEDIAASYNCPORT_2_DRVDISKINTEGRITY(pInterface);1235 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)pvUser;1236 int rc = VINF_SUCCESS;1237 1238 LogFlowFunc(("pIoReq=%#p\n", pIoReq));1239 1240 /* Remove from the active list. */1241 if (pThis->fTraceRequests)1242 drvdiskintIoReqRemove(pThis, pIoReq);1243 1244 if (RT_SUCCESS(rcReq) && pThis->fCheckConsistency)1245 {1246 if (pIoReq->enmTxDir == DRVDISKAIOTXDIR_READ)1247 rc = drvdiskintReadVerify(pThis, pIoReq->paSeg, pIoReq->cSeg, pIoReq->off, pIoReq->cbTransfer);1248 else if ( pIoReq->enmTxDir == DRVDISKAIOTXDIR_WRITE1249 && !pThis->fRecordWriteBeforeCompletion)1250 rc = drvdiskintWriteRecord(pThis, pIoReq->paSeg, pIoReq->cSeg, pIoReq->off, pIoReq->cbTransfer);1251 else if (pIoReq->enmTxDir == DRVDISKAIOTXDIR_DISCARD)1252 rc = drvdiskintDiscardRecords(pThis, pIoReq->paRanges, pIoReq->cRanges);1253 else if (pIoReq->enmTxDir == DRVDISKAIOTXDIR_READ_AFTER_WRITE)1254 rc = drvdiskintReadAfterWriteVerify(pThis, pIoReq);1255 else1256 AssertMsg( pIoReq->enmTxDir == DRVDISKAIOTXDIR_FLUSH1257 || ( pIoReq->enmTxDir == DRVDISKAIOTXDIR_WRITE1258 && pThis->fRecordWriteBeforeCompletion), ("Huh?\n"));1259 1260 AssertRC(rc);1261 }1262 1263 if (pThis->hIoLogger)1264 {1265 RTSGBUF SgBuf;1266 1267 if (pIoReq->enmTxDir == DRVDISKAIOTXDIR_READ)1268 RTSgBufInit(&SgBuf, pIoReq->paSeg, pIoReq->cSeg);1269 1270 int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, pIoReq->hIoLogEntry, rc, &SgBuf);1271 AssertRC(rc2);1272 }1273 1274 if ( pThis->fReadAfterWrite1275 && pIoReq->enmTxDir == DRVDISKAIOTXDIR_WRITE)1276 {1277 pIoReq->enmTxDir = DRVDISKAIOTXDIR_READ_AFTER_WRITE;1278 1279 /* Add again because it was removed above. */1280 if (pThis->fTraceRequests)1281 drvdiskintIoReqAdd(pThis, pIoReq);1282 1283 rc = pThis->pDrvMediaAsync->pfnStartRead(pThis->pDrvMediaAsync, pIoReq->off, pIoReq->paSeg, pIoReq->cSeg,1284 pIoReq->cbTransfer, pIoReq);1285 if (rc == VINF_VD_ASYNC_IO_FINISHED)1286 {1287 rc = drvdiskintReadAfterWriteVerify(pThis, pIoReq);1288 1289 if (pThis->fTraceRequests)1290 drvdiskintIoReqRemove(pThis, pIoReq);1291 RTMemFree(pIoReq);1292 }1293 else if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)1294 rc = VINF_SUCCESS;1295 else if (RT_FAILURE(rc))1296 RTMemFree(pIoReq);1297 }1298 else1299 {1300 void *pvUserComplete = pIoReq->pvUser;1301 drvdiskintReqFree(pThis, pIoReq);1302 1303 rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvUserComplete, rcReq);1304 }1305 1306 return rc;1307 979 } 1308 980 … … 1859 1531 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase); 1860 1532 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia); 1861 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAASYNC, pThis->pDrvMediaAsync ? &pThis->IMediaAsync : NULL);1862 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAASYNCPORT, &pThis->IMediaAsyncPort);1863 1533 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAPORT, &pThis->IMediaPort); 1864 1534 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAEXPORT, &pThis->IMediaExPort); … … 1995 1665 pThis->IMedia.pfnReadPcBios = drvdiskintReadPcBios; 1996 1666 1997 /* IMediaAsync */1998 pThis->IMediaAsync.pfnStartRead = drvdiskintStartRead;1999 pThis->IMediaAsync.pfnStartWrite = drvdiskintStartWrite;2000 pThis->IMediaAsync.pfnStartFlush = drvdiskintStartFlush;2001 2002 1667 /* IMediaEx. */ 2003 1668 pThis->IMediaEx.pfnIoReqAllocSizeSet = drvdiskintIoReqAllocSizeSet; … … 2016 1681 pThis->IMediaEx.pfnIoReqSuspendedLoad = drvdiskintIoReqSuspendedLoad; 2017 1682 2018 /* IMediaAsyncPort. */2019 pThis->IMediaAsyncPort.pfnTransferCompleteNotify = drvdiskintAsyncTransferCompleteNotify;2020 2021 1683 /* IMediaPort. */ 2022 1684 pThis->IMediaPort.pfnQueryDeviceLocation = drvdiskintQueryDeviceLocation; … … 2034 1696 return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_BELOW, 2035 1697 N_("No media port inrerface above")); 2036 2037 /* Try to attach async media port interface above.*/2038 pThis->pDrvMediaAsyncPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAASYNCPORT);2039 1698 2040 1699 /* Try to attach extended media port interface above.*/ … … 2055 1714 N_("No media or async media interface below")); 2056 1715 2057 pThis->pDrvMediaAsync = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIAASYNC);2058 1716 pThis->pDrvMediaEx = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIAEX); 2059 1717 2060 1718 if (pThis->pDrvMedia->pfnDiscard) 2061 1719 pThis->IMedia.pfnDiscard = drvdiskintDiscard; 2062 if ( pThis->pDrvMediaAsync2063 && pThis->pDrvMediaAsync->pfnStartDiscard)2064 pThis->IMediaAsync.pfnStartDiscard = drvdiskintStartDiscard;2065 1720 2066 1721 if (pThis->fCheckConsistency) -
trunk/src/VBox/Devices/Storage/DrvRamDisk.cpp
r63997 r64002 174 174 /** Media port interface */ 175 175 PDMIMEDIAPORT IMediaPort; 176 /** Our media async interface */177 PDMIMEDIAASYNC IMediaAsync;178 179 /** The async media port interface above. */180 PPDMIMEDIAASYNCPORT pDrvMediaAsyncPort;181 176 182 177 /** Flag whether the RAM disk was pre allocated. */ … … 540 535 } 541 536 542 /**543 * Worker for a read request.544 *545 * @returns VBox status code.546 * @param pThis RAM disk container instance data.547 * @param pIoReq The read request.548 */549 static DECLCALLBACK(int) drvramdiskAsyncReadWorker(PDRVRAMDISK pThis, uint64_t uOffset, PCRTSGSEG paSeg,550 unsigned cSeg, size_t cbRead, void *pvUser)551 {552 RTSGBUF SgBuf;553 554 RTSgBufInit(&SgBuf, paSeg, cSeg);555 int rc = drvramdiskReadWorker(pThis, &SgBuf, uOffset, cbRead);556 pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvUser, rc);557 return VINF_SUCCESS;558 }559 560 /**561 * Worker for a write request.562 *563 * @returns VBox status code.564 * @param pThis RAM disk container instance data.565 * @param pIoReq The read request.566 */567 static DECLCALLBACK(int) drvramdiskAsyncWriteWorker(PDRVRAMDISK pThis, uint64_t uOffset, PCRTSGSEG paSeg,568 unsigned cSeg, size_t cbWrite, void *pvUser)569 {570 RTSGBUF SgBuf;571 572 RTSgBufInit(&SgBuf, paSeg, cSeg);573 int rc = drvramdiskWriteWorker(pThis, &SgBuf, uOffset, cbWrite);574 pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvUser, rc);575 return VINF_SUCCESS;576 }577 578 /**579 * Worker for a flush request.580 *581 * @returns VBox status code.582 * @param pThis RAM disk container instance data.583 * @param pIoReq The read request.584 */585 static DECLCALLBACK(int) drvramdiskAsyncFlushWorker(PDRVRAMDISK pThis, void *pvUser)586 {587 pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort,588 pvUser, VINF_SUCCESS);589 return VINF_SUCCESS;590 }591 592 /**593 * Worker for a write request.594 *595 * @returns VBox status code.596 * @param pThis RAM disk container instance data.597 * @param pIoReq The read request.598 */599 static DECLCALLBACK(int) drvramdiskAsyncDiscardWorker(PDRVRAMDISK pThis, PCRTRANGE paRanges,600 unsigned cRanges, void *pvUser)601 {602 int rc = drvramdiskDiscardRecords(pThis, paRanges, cRanges);603 pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvUser, rc);604 return VINF_SUCCESS;605 }606 607 /** @copydoc PDMIMEDIAASYNC::pfnStartRead */608 static DECLCALLBACK(int) drvramdiskStartRead(PPDMIMEDIAASYNC pInterface, uint64_t uOffset,609 PCRTSGSEG paSeg, unsigned cSeg,610 size_t cbRead, void *pvUser)611 {612 PDRVRAMDISK pThis = RT_FROM_MEMBER(pInterface, DRVRAMDISK, IMediaAsync);613 614 int rc = RTReqQueueCallEx(pThis->hReqQ, NULL, 0, RTREQFLAGS_NO_WAIT,615 (PFNRT)drvramdiskAsyncReadWorker, 6, pThis, uOffset,616 paSeg, cSeg, cbRead, pvUser);617 if (rc == VINF_SUCCESS)618 rc = VERR_VD_ASYNC_IO_IN_PROGRESS;619 620 return rc;621 }622 623 /** @copydoc PDMIMEDIAASYNC::pfnStartWrite */624 static DECLCALLBACK(int) drvramdiskStartWrite(PPDMIMEDIAASYNC pInterface, uint64_t uOffset,625 PCRTSGSEG paSeg, unsigned cSeg,626 size_t cbWrite, void *pvUser)627 {628 PDRVRAMDISK pThis = RT_FROM_MEMBER(pInterface, DRVRAMDISK, IMediaAsync);629 630 int rc = RTReqQueueCallEx(pThis->hReqQ, NULL, 0, RTREQFLAGS_NO_WAIT,631 (PFNRT)drvramdiskAsyncWriteWorker, 6, pThis, uOffset,632 paSeg, cSeg, cbWrite, pvUser);633 if (rc == VINF_SUCCESS)634 rc = VERR_VD_ASYNC_IO_IN_PROGRESS;635 636 return rc;637 }638 639 /** @copydoc PDMIMEDIAASYNC::pfnStartFlush */640 static DECLCALLBACK(int) drvramdiskStartFlush(PPDMIMEDIAASYNC pInterface, void *pvUser)641 {642 PDRVRAMDISK pThis = RT_FROM_MEMBER(pInterface, DRVRAMDISK, IMediaAsync);643 644 int rc = RTReqQueueCallEx(pThis->hReqQ, NULL, 0, RTREQFLAGS_NO_WAIT,645 (PFNRT)drvramdiskAsyncFlushWorker, 2, pThis, pvUser);646 if (rc == VINF_SUCCESS)647 rc = VERR_VD_ASYNC_IO_IN_PROGRESS;648 649 return rc;650 }651 652 /** @copydoc PDMIMEDIAASYNC::pfnStartDiscard */653 static DECLCALLBACK(int) drvramdiskStartDiscard(PPDMIMEDIAASYNC pInterface, PCRTRANGE paRanges, unsigned cRanges, void *pvUser)654 {655 PDRVRAMDISK pThis = RT_FROM_MEMBER(pInterface, DRVRAMDISK, IMediaAsync);656 657 int rc = RTReqQueueCallEx(pThis->hReqQ, NULL, 0, RTREQFLAGS_NO_WAIT,658 (PFNRT)drvramdiskAsyncDiscardWorker, 4, pThis, paRanges,659 cRanges, pvUser);660 if (rc == VINF_SUCCESS)661 rc = VERR_VD_ASYNC_IO_IN_PROGRESS;662 663 return rc;664 }665 666 537 /** @copydoc PDMIMEDIA::pfnFlush */ 667 538 static DECLCALLBACK(int) drvramdiskFlush(PPDMIMEDIA pInterface) … … 1700 1571 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia); 1701 1572 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAEX, &pThis->IMediaEx); 1702 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAASYNC, &pThis->IMediaAsync);1703 1573 1704 1574 return NULL; … … 1796 1666 pThis->IMedia.pfnDiscard = drvramdiskDiscard; 1797 1667 1798 /* IMediaAsync */1799 pThis->IMediaAsync.pfnStartRead = drvramdiskStartRead;1800 pThis->IMediaAsync.pfnStartWrite = drvramdiskStartWrite;1801 pThis->IMediaAsync.pfnStartFlush = drvramdiskStartFlush;1802 pThis->IMediaAsync.pfnStartDiscard = drvramdiskStartDiscard;1803 1804 1668 /* IMediaEx */ 1805 1669 pThis->IMediaEx.pfnIoReqAllocSizeSet = drvramdiskIoReqAllocSizeSet; … … 1824 1688 N_("No media port interface above")); 1825 1689 1826 /* Try to attach async media port interface above.*/1827 pThis->pDrvMediaAsyncPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAASYNCPORT);1828 1829 1690 /* Try to attach extended media port interface above.*/ 1830 1691 pThis->pDrvMediaExPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAEXPORT); … … 1857 1718 rc = VERR_NO_MEMORY; 1858 1719 1859 if (pThis->pDrvMedia AsyncPort || pThis->pDrvMediaExPort)1720 if (pThis->pDrvMediaExPort) 1860 1721 { 1861 1722 rc = RTReqQueueCreate(&pThis->hReqQ); -
trunk/src/VBox/Devices/Storage/DrvVD.cpp
r63997 r64002 98 98 ( (PVBOXDISK)((uintptr_t)pInterface - RT_OFFSETOF(VBOXDISK, IMedia)) ) 99 99 100 /** Converts a pointer to VBOXDISK::IMediaAsync to a PVBOXDISK. */101 #define PDMIMEDIAASYNC_2_VBOXDISK(pInterface) \102 ( (PVBOXDISK)((uintptr_t)pInterface - RT_OFFSETOF(VBOXDISK, IMediaAsync)) )103 104 100 /** Saved state version of an I/O request .*/ 105 101 #define DRVVD_IOREQ_SAVED_STATE_VERSION UINT32_C(1) … … 117 113 { 118 114 /** Pointer to next image. */ 119 struct VBOXIMAGE 115 struct VBOXIMAGE *pNext; 120 116 /** Pointer to list of VD interfaces. Per-image. */ 121 117 PVDINTERFACE pVDIfsImage; … … 245 241 * 246 242 * @implements PDMIMEDIA 247 * @implements PDMIMEDIAASYNC248 243 * @implements PDMIMEDIAEX 249 244 * @implements PDMIMOUNT … … 276 271 /** Flag whether opened disk supports async I/O operations. */ 277 272 bool fAsyncIOSupported; 278 /** The async media interface. */279 PDMIMEDIAASYNC IMediaAsync;280 /** The async media port interface above. */281 PPDMIMEDIAASYNCPORT pDrvMediaAsyncPort;282 273 /** Pointer to the list of data we need to keep per image. */ 283 274 PVBOXIMAGE pImages; … … 2500 2491 2501 2492 2502 /*********************************************************************************************************************************2503 * Async Media interface methods *2504 *********************************************************************************************************************************/2505 2506 2493 static DECLCALLBACK(void) drvvdBlkCacheReqComplete(void *pvUser1, void *pvUser2, int rcReq) 2507 2494 { … … 2512 2499 } 2513 2500 2514 static DECLCALLBACK(void) drvvdAsyncReqComplete(void *pvUser1, void *pvUser2, int rcReq)2515 {2516 PVBOXDISK pThis = (PVBOXDISK)pvUser1;2517 2518 int rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort,2519 pvUser2, rcReq);2520 AssertRC(rc);2521 }2522 2523 static DECLCALLBACK(int) drvvdStartRead(PPDMIMEDIAASYNC pInterface, uint64_t uOffset,2524 PCRTSGSEG paSeg, unsigned cSeg,2525 size_t cbRead, void *pvUser)2526 {2527 LogFlowFunc(("uOffset=%#llx paSeg=%#p cSeg=%u cbRead=%d pvUser=%#p\n",2528 uOffset, paSeg, cSeg, cbRead, pvUser));2529 int rc = VINF_SUCCESS;2530 PVBOXDISK pThis = PDMIMEDIAASYNC_2_VBOXDISK(pInterface);2531 2532 /*2533 * Check the state.2534 */2535 if (!pThis->pDisk)2536 {2537 AssertMsgFailed(("Invalid state! Not mounted!\n"));2538 return VERR_PDM_MEDIA_NOT_MOUNTED;2539 }2540 2541 rc = drvvdKeyCheckPrereqs(pThis, true /* fSetError */);2542 if (RT_FAILURE(rc))2543 return rc;2544 2545 pThis->fBootAccelActive = false;2546 2547 RTSGBUF SgBuf;2548 RTSgBufInit(&SgBuf, paSeg, cSeg);2549 if (!pThis->pBlkCache)2550 rc = VDAsyncRead(pThis->pDisk, uOffset, cbRead, &SgBuf,2551 drvvdAsyncReqComplete, pThis, pvUser);2552 else2553 {2554 rc = PDMR3BlkCacheRead(pThis->pBlkCache, uOffset, &SgBuf, cbRead, pvUser);2555 if (rc == VINF_AIO_TASK_PENDING)2556 rc = VERR_VD_ASYNC_IO_IN_PROGRESS;2557 else if (rc == VINF_SUCCESS)2558 rc = VINF_VD_ASYNC_IO_FINISHED;2559 }2560 2561 LogFlowFunc(("returns %Rrc\n", rc));2562 return rc;2563 }2564 2565 static DECLCALLBACK(int) drvvdStartWrite(PPDMIMEDIAASYNC pInterface, uint64_t uOffset,2566 PCRTSGSEG paSeg, unsigned cSeg,2567 size_t cbWrite, void *pvUser)2568 {2569 LogFlowFunc(("uOffset=%#llx paSeg=%#p cSeg=%u cbWrite=%d pvUser=%#p\n",2570 uOffset, paSeg, cSeg, cbWrite, pvUser));2571 int rc = VINF_SUCCESS;2572 PVBOXDISK pThis = PDMIMEDIAASYNC_2_VBOXDISK(pInterface);2573 2574 /*2575 * Check the state.2576 */2577 if (!pThis->pDisk)2578 {2579 AssertMsgFailed(("Invalid state! Not mounted!\n"));2580 return VERR_PDM_MEDIA_NOT_MOUNTED;2581 }2582 2583 rc = drvvdKeyCheckPrereqs(pThis, true /* fSetError */);2584 if (RT_FAILURE(rc))2585 return rc;2586 2587 pThis->fBootAccelActive = false;2588 2589 RTSGBUF SgBuf;2590 RTSgBufInit(&SgBuf, paSeg, cSeg);2591 2592 if (!pThis->pBlkCache)2593 rc = VDAsyncWrite(pThis->pDisk, uOffset, cbWrite, &SgBuf,2594 drvvdAsyncReqComplete, pThis, pvUser);2595 else2596 {2597 rc = PDMR3BlkCacheWrite(pThis->pBlkCache, uOffset, &SgBuf, cbWrite, pvUser);2598 if (rc == VINF_AIO_TASK_PENDING)2599 rc = VERR_VD_ASYNC_IO_IN_PROGRESS;2600 else if (rc == VINF_SUCCESS)2601 rc = VINF_VD_ASYNC_IO_FINISHED;2602 }2603 2604 LogFlowFunc(("returns %Rrc\n", rc));2605 return rc;2606 }2607 2608 static DECLCALLBACK(int) drvvdStartFlush(PPDMIMEDIAASYNC pInterface, void *pvUser)2609 {2610 LogFlowFunc(("pvUser=%#p\n", pvUser));2611 int rc = VINF_SUCCESS;2612 PVBOXDISK pThis = PDMIMEDIAASYNC_2_VBOXDISK(pInterface);2613 2614 /*2615 * Check the state.2616 */2617 if (!pThis->pDisk)2618 {2619 AssertMsgFailed(("Invalid state! Not mounted!\n"));2620 return VERR_PDM_MEDIA_NOT_MOUNTED;2621 }2622 2623 #ifdef VBOX_IGNORE_FLUSH2624 if (pThis->fIgnoreFlushAsync)2625 return VINF_VD_ASYNC_IO_FINISHED;2626 #endif /* VBOX_IGNORE_FLUSH */2627 2628 if (!pThis->pBlkCache)2629 rc = VDAsyncFlush(pThis->pDisk, drvvdAsyncReqComplete, pThis, pvUser);2630 else2631 {2632 rc = PDMR3BlkCacheFlush(pThis->pBlkCache, pvUser);2633 if (rc == VINF_AIO_TASK_PENDING)2634 rc = VERR_VD_ASYNC_IO_IN_PROGRESS;2635 else if (rc == VINF_SUCCESS)2636 rc = VINF_VD_ASYNC_IO_FINISHED;2637 }2638 LogFlowFunc(("returns %Rrc\n", rc));2639 return rc;2640 }2641 2642 static DECLCALLBACK(int) drvvdStartDiscard(PPDMIMEDIAASYNC pInterface, PCRTRANGE paRanges,2643 unsigned cRanges, void *pvUser)2644 {2645 int rc = VINF_SUCCESS;2646 PVBOXDISK pThis = PDMIMEDIAASYNC_2_VBOXDISK(pInterface);2647 2648 LogFlowFunc(("paRanges=%#p cRanges=%u pvUser=%#p\n",2649 paRanges, cRanges, pvUser));2650 2651 /*2652 * Check the state.2653 */2654 if (!pThis->pDisk)2655 {2656 AssertMsgFailed(("Invalid state! Not mounted!\n"));2657 return VERR_PDM_MEDIA_NOT_MOUNTED;2658 }2659 2660 if (!pThis->pBlkCache)2661 rc = VDAsyncDiscardRanges(pThis->pDisk, paRanges, cRanges, drvvdAsyncReqComplete,2662 pThis, pvUser);2663 else2664 {2665 rc = PDMR3BlkCacheDiscard(pThis->pBlkCache, paRanges, cRanges, pvUser);2666 if (rc == VINF_AIO_TASK_PENDING)2667 rc = VERR_VD_ASYNC_IO_IN_PROGRESS;2668 else if (rc == VINF_SUCCESS)2669 rc = VINF_VD_ASYNC_IO_FINISHED;2670 }2671 LogFlowFunc(("returns %Rrc\n", rc));2672 return rc;2673 }2674 2675 /** @copydoc FNPDMBLKCACHEXFERCOMPLETEDRV */2676 static DECLCALLBACK(void) drvvdBlkCacheXferComplete(PPDMDRVINS pDrvIns, void *pvUser, int rcReq)2677 {2678 PVBOXDISK pThis = PDMINS_2_DATA(pDrvIns, PVBOXDISK);2679 2680 int rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort,2681 pvUser, rcReq);2682 AssertRC(rc);2683 }2684 2501 2685 2502 /** @copydoc FNPDMBLKCACHEXFERCOMPLETEDRV */ … … 3131 2948 { 3132 2949 if (pThis->pBlkCache) 2950 { 3133 2951 rc = PDMR3BlkCacheRead(pThis->pBlkCache, pIoReq->ReadWrite.offStart, 3134 2952 &pIoReq->ReadWrite.IoBuf.SgBuf, cbReqIo, pIoReq); 2953 if (rc == VINF_SUCCESS) 2954 rc = VINF_VD_ASYNC_IO_FINISHED; 2955 else if (rc == VINF_AIO_TASK_PENDING) 2956 rc = VERR_VD_ASYNC_IO_IN_PROGRESS; 2957 } 3135 2958 else 3136 2959 rc = VDAsyncRead(pThis->pDisk, pIoReq->ReadWrite.offStart, cbReqIo, &pIoReq->ReadWrite.IoBuf.SgBuf, … … 3168 2991 { 3169 2992 if (pThis->pBlkCache) 2993 { 3170 2994 rc = PDMR3BlkCacheWrite(pThis->pBlkCache, pIoReq->ReadWrite.offStart, 3171 2995 &pIoReq->ReadWrite.IoBuf.SgBuf, cbReqIo, pIoReq); 2996 if (rc == VINF_SUCCESS) 2997 rc = VINF_VD_ASYNC_IO_FINISHED; 2998 else if (rc == VINF_AIO_TASK_PENDING) 2999 rc = VERR_VD_ASYNC_IO_IN_PROGRESS; 3000 } 3172 3001 else 3173 3002 rc = VDAsyncWrite(pThis->pDisk, pIoReq->ReadWrite.offStart, cbReqIo, &pIoReq->ReadWrite.IoBuf.SgBuf, … … 3203 3032 { 3204 3033 if (pThis->pBlkCache) 3034 { 3205 3035 rc = PDMR3BlkCacheFlush(pThis->pBlkCache, pIoReq); 3036 if (rc == VINF_SUCCESS) 3037 rc = VINF_VD_ASYNC_IO_FINISHED; 3038 else if (rc == VINF_AIO_TASK_PENDING) 3039 rc = VERR_VD_ASYNC_IO_IN_PROGRESS; 3040 } 3206 3041 else 3207 3042 rc = VDAsyncFlush(pThis->pDisk, drvvdMediaExIoReqComplete, pThis, pIoReq); … … 3231 3066 { 3232 3067 if (pThis->pBlkCache) 3068 { 3233 3069 rc = PDMR3BlkCacheDiscard(pThis->pBlkCache, pIoReq->Discard.paRanges, pIoReq->Discard.cRanges, pIoReq); 3070 if (rc == VINF_SUCCESS) 3071 rc = VINF_VD_ASYNC_IO_FINISHED; 3072 else if (rc == VINF_AIO_TASK_PENDING) 3073 rc = VERR_VD_ASYNC_IO_IN_PROGRESS; 3074 } 3234 3075 else 3235 3076 rc = VDAsyncDiscardRanges(pThis->pDisk, pIoReq->Discard.paRanges, pIoReq->Discard.cRanges, … … 4157 3998 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia); 4158 3999 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUNT, pThis->fMountable ? &pThis->IMount : NULL); 4159 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAASYNC, pThis->fAsyncIOSupported ? &pThis->IMediaAsync : NULL);4160 4000 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAEX, pThis->pDrvMediaExPort ? &pThis->IMediaEx : NULL); 4161 4001 return NULL; … … 4516 4356 pThis->IMount.pfnIsLocked = drvvdIsLocked; 4517 4357 4518 /* IMediaAsync */4519 pThis->IMediaAsync.pfnStartRead = drvvdStartRead;4520 pThis->IMediaAsync.pfnStartWrite = drvvdStartWrite;4521 pThis->IMediaAsync.pfnStartFlush = drvvdStartFlush;4522 pThis->IMediaAsync.pfnStartDiscard = drvvdStartDiscard;4523 4524 4358 /* IMediaEx */ 4525 4359 pThis->IMediaEx.pfnQueryFeatures = drvvdQueryFeatures; … … 4559 4393 N_("No media port interface above")); 4560 4394 4561 /* Try to attach async media port interface above.*/4562 pThis->pDrvMediaAsyncPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAASYNCPORT);4563 4395 pThis->pDrvMountNotify = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMOUNTNOTIFY); 4564 4396 … … 4966 4798 } 4967 4799 4968 if (pThis->pDrvMedia AsyncPort && fUseNewIo)4800 if (pThis->pDrvMediaExPort && fUseNewIo) 4969 4801 pThis->fAsyncIOSupported = true; 4970 4802 … … 5211 5043 { 5212 5044 pThis->IMedia.pfnDiscard = NULL; 5213 pThis->IMediaAsync.pfnStartDiscard = NULL;5214 5045 pThis->IMediaEx.pfnIoReqDiscard = NULL; 5215 5046 } … … 5333 5164 if (cbStr > 0) 5334 5165 { 5335 bool fMediaEx = strcmp(pcszController, "nvme") == 0 ? true : false;5336 5166 rc = PDMDrvHlpBlkCacheRetain(pDrvIns, &pThis->pBlkCache, 5337 fMediaEx ? drvvdBlkCacheXferCompleteIoReq 5338 : drvvdBlkCacheXferComplete, 5167 drvvdBlkCacheXferCompleteIoReq, 5339 5168 drvvdBlkCacheXferEnqueue, 5340 5169 drvvdBlkCacheXferEnqueueDiscard,
Note:
See TracChangeset
for help on using the changeset viewer.