Changeset 64320 in vbox for trunk/src/VBox
- Timestamp:
- Oct 19, 2016 2:55:59 PM (8 years ago)
- Location:
- trunk/src/VBox/Devices/Storage
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DrvHostBase.cpp
r64316 r64320 68 68 } 69 69 else 70 Log(("%s-%d: drvHostBaseRead Os: drvHostBaseReadOs(%#llx, %p, %#x) -> %Rrc ('%s')\n",70 Log(("%s-%d: drvHostBaseRead: drvHostBaseReadOs(%#llx, %p, %#x) -> %Rrc ('%s')\n", 71 71 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, 72 72 off, pvBuf, cbRead, rc, pThis->pszDevice)); … … 217 217 RTCritSectLeave(&pThis->CritSect); 218 218 LogFlow(("%s-%d: %s: returns %Rrc CHS={%d,%d,%d}\n", 219 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, __FUNCTION__, rc, pThis->PCHSGeometry.cCylinders, pThis->PCHSGeometry.cHeads, pThis->PCHSGeometry.cSectors)); 219 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, __FUNCTION__, rc, 220 pThis->PCHSGeometry.cCylinders, pThis->PCHSGeometry.cHeads, pThis->PCHSGeometry.cSectors)); 220 221 return rc; 221 222 } … … 227 228 PDRVHOSTBASE pThis = RT_FROM_MEMBER(pInterface, DRVHOSTBASE, IMedia); 228 229 LogFlow(("%s-%d: %s: cCylinders=%d cHeads=%d cSectors=%d\n", 229 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, __FUNCTION__, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors)); 230 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, __FUNCTION__, 231 pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors)); 230 232 RTCritSectEnter(&pThis->CritSect); 231 233 … … 269 271 RTCritSectLeave(&pThis->CritSect); 270 272 LogFlow(("%s-%d: %s: returns %Rrc CHS={%d,%d,%d}\n", 271 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, __FUNCTION__, rc, pThis->LCHSGeometry.cCylinders, pThis->LCHSGeometry.cHeads, pThis->LCHSGeometry.cSectors)); 273 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, __FUNCTION__, rc, 274 pThis->LCHSGeometry.cCylinders, pThis->LCHSGeometry.cHeads, pThis->LCHSGeometry.cSectors)); 272 275 return rc; 273 276 } … … 279 282 PDRVHOSTBASE pThis = RT_FROM_MEMBER(pInterface, DRVHOSTBASE, IMedia); 280 283 LogFlow(("%s-%d: %s: cCylinders=%d cHeads=%d cSectors=%d\n", 281 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, __FUNCTION__, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors)); 284 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, __FUNCTION__, 285 pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors)); 282 286 RTCritSectEnter(&pThis->CritSect); 283 287 … … 303 307 PDRVHOSTBASE pThis = RT_FROM_MEMBER(pInterface, DRVHOSTBASE, IMedia); 304 308 return pThis->fBiosVisible; 309 } 310 311 312 313 /* -=-=-=-=- IMediaEx -=-=-=-=- */ 314 315 DECLHIDDEN(int) drvHostBaseBufferRetain(PDRVHOSTBASE pThis, PDRVHOSTBASEREQ pReq, size_t cbBuf, bool fWrite, void **ppvBuf) 316 { 317 int rc = VINF_SUCCESS; 318 319 if (pThis->cbBuf < cbBuf) 320 { 321 RTMemFree(pThis->pvBuf); 322 pThis->cbBuf = 0; 323 pThis->pvBuf = RTMemAlloc(cbBuf); 324 if (pThis->pvBuf) 325 pThis->cbBuf = cbBuf; 326 else 327 rc = VERR_NO_MEMORY; 328 } 329 330 if (RT_SUCCESS(rc) && fWrite) 331 { 332 RTSGSEG Seg; 333 RTSGBUF SgBuf; 334 335 Seg.pvSeg = pThis->pvBuf; 336 Seg.cbSeg = cbBuf; 337 RTSgBufInit(&SgBuf, &Seg, 1); 338 rc = pThis->pDrvMediaExPort->pfnIoReqCopyToBuf(pThis->pDrvMediaExPort, (PDMMEDIAEXIOREQ)pReq, 339 &pReq->abAlloc[0], 0, &SgBuf, cbBuf); 340 } 341 342 if (RT_SUCCESS(rc)) 343 *ppvBuf = pThis->pvBuf; 344 345 return rc; 346 } 347 348 DECLHIDDEN(int) drvHostBaseBufferRelease(PDRVHOSTBASE pThis, PDRVHOSTBASEREQ pReq, size_t cbBuf, bool fWrite, void *pvBuf) 349 { 350 int rc = VINF_SUCCESS; 351 352 if (!fWrite) 353 { 354 RTSGSEG Seg; 355 RTSGBUF SgBuf; 356 357 Seg.pvSeg = pvBuf; 358 Seg.cbSeg = cbBuf; 359 RTSgBufInit(&SgBuf, &Seg, 1); 360 rc = pThis->pDrvMediaExPort->pfnIoReqCopyFromBuf(pThis->pDrvMediaExPort, (PDMMEDIAEXIOREQ)pReq, 361 &pReq->abAlloc[0], 0, &SgBuf, cbBuf); 362 } 363 364 return rc; 365 } 366 367 /** @interface_method_impl{PDMIMEDIAEX,pfnQueryFeatures} */ 368 static DECLCALLBACK(int) drvHostBaseQueryFeatures(PPDMIMEDIAEX pInterface, uint32_t *pfFeatures) 369 { 370 PDRVHOSTBASE pThis = RT_FROM_MEMBER(pInterface, DRVHOSTBASE, IMediaEx); 371 372 *pfFeatures = pThis->IMediaEx.pfnIoReqSendScsiCmd ? PDMIMEDIAEX_FEATURE_F_RAWSCSICMD : 0; 373 return VINF_SUCCESS; 374 } 375 376 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqAllocSizeSet} */ 377 static DECLCALLBACK(int) drvHostBaseIoReqAllocSizeSet(PPDMIMEDIAEX pInterface, size_t cbIoReqAlloc) 378 { 379 PDRVHOSTBASE pThis = RT_FROM_MEMBER(pInterface, DRVHOSTBASE, IMediaEx); 380 381 pThis->cbIoReqAlloc = RT_OFFSETOF(DRVHOSTBASEREQ, abAlloc[cbIoReqAlloc]); 382 return VINF_SUCCESS; 383 } 384 385 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqAlloc} */ 386 static DECLCALLBACK(int) drvHostBaseIoReqAlloc(PPDMIMEDIAEX pInterface, PPDMMEDIAEXIOREQ phIoReq, void **ppvIoReqAlloc, 387 PDMMEDIAEXIOREQID uIoReqId, uint32_t fFlags) 388 { 389 RT_NOREF2(uIoReqId, fFlags); 390 391 int rc = VINF_SUCCESS; 392 PDRVHOSTBASE pThis = RT_FROM_MEMBER(pInterface, DRVHOSTBASE, IMediaEx); 393 PDRVHOSTBASEREQ pReq = (PDRVHOSTBASEREQ)RTMemAllocZ(pThis->cbIoReqAlloc); 394 if (RT_LIKELY(pReq)) 395 { 396 *phIoReq = (PDMMEDIAEXIOREQ)pReq; 397 *ppvIoReqAlloc = &pReq->abAlloc[0]; 398 } 399 else 400 rc = VERR_NO_MEMORY; 401 402 return rc; 403 } 404 405 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqFree} */ 406 static DECLCALLBACK(int) drvHostBaseIoReqFree(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq) 407 { 408 RT_NOREF1(pInterface); 409 PDRVHOSTBASEREQ pReq = (PDRVHOSTBASEREQ)hIoReq; 410 411 RTMemFree(pReq); 412 return VINF_SUCCESS; 413 } 414 415 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqQueryResidual} */ 416 static DECLCALLBACK(int) drvHostBaseIoReqQueryResidual(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, size_t *pcbResidual) 417 { 418 RT_NOREF2(pInterface, hIoReq); 419 420 *pcbResidual = 0; /** @todo: Implement. */ 421 return VINF_SUCCESS; 422 } 423 424 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqCancelAll} */ 425 static DECLCALLBACK(int) drvHostBaseIoReqCancelAll(PPDMIMEDIAEX pInterface) 426 { 427 RT_NOREF1(pInterface); 428 return VINF_SUCCESS; 429 } 430 431 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqCancel} */ 432 static DECLCALLBACK(int) drvHostBaseIoReqCancel(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQID uIoReqId) 433 { 434 RT_NOREF2(pInterface, uIoReqId); 435 return VERR_PDM_MEDIAEX_IOREQID_NOT_FOUND; 436 } 437 438 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqRead} */ 439 static DECLCALLBACK(int) drvHostBaseIoReqRead(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, uint64_t off, size_t cbRead) 440 { 441 PDRVHOSTBASE pThis = RT_FROM_MEMBER(pInterface, DRVHOSTBASE, IMediaEx); 442 PDRVHOSTBASEREQ pReq = (PDRVHOSTBASEREQ)hIoReq; 443 LogFlow(("%s-%d: drvHostBaseIoReqRead: off=%#llx cbRead=%#x (%s)\n", 444 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, off, cbRead, pThis->pszDevice)); 445 RTCritSectEnter(&pThis->CritSect); 446 447 /* 448 * Check the state. 449 */ 450 int rc; 451 if (pThis->fMediaPresent) 452 { 453 void *pvBuf; 454 rc = drvHostBaseBufferRetain(pThis, pReq, cbRead, false, &pvBuf); 455 if (RT_SUCCESS(rc)) 456 { 457 /* 458 * Seek and read. 459 */ 460 rc = drvHostBaseReadOs(pThis, off, pvBuf, cbRead); 461 if (RT_SUCCESS(rc)) 462 { 463 Log2(("%s-%d: drvHostBaseReadOs: off=%#llx cbRead=%#x\n" 464 "%16.*Rhxd\n", 465 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, off, cbRead, cbRead, pvBuf)); 466 } 467 else 468 Log(("%s-%d: drvHostBaseIoReqRead: drvHostBaseReadOs(%#llx, %p, %#x) -> %Rrc ('%s')\n", 469 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, 470 off, pvBuf, cbRead, rc, pThis->pszDevice)); 471 472 rc = drvHostBaseBufferRelease(pThis, pReq, cbRead, false, pvBuf); 473 } 474 else 475 Log(("%s-%d: drvHostBaseIoReqRead: drvHostBaseBufferRetain(%#llx, %p, %#x) -> %Rrc ('%s')\n", 476 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, 477 off, pvBuf, cbRead, rc, pThis->pszDevice)); 478 } 479 else 480 rc = VERR_MEDIA_NOT_PRESENT; 481 482 RTCritSectLeave(&pThis->CritSect); 483 LogFlow(("%s-%d: drvHostBaseIoReqRead: returns %Rrc\n", pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, rc)); 484 return rc; 485 } 486 487 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqWrite} */ 488 static DECLCALLBACK(int) drvHostBaseIoReqWrite(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, uint64_t off, size_t cbWrite) 489 { 490 PDRVHOSTBASE pThis = RT_FROM_MEMBER(pInterface, DRVHOSTBASE, IMediaEx); 491 PDRVHOSTBASEREQ pReq = (PDRVHOSTBASEREQ)hIoReq; 492 LogFlow(("%s-%d: drvHostBaseIoReqWrite: off=%#llx cbWrite=%#x (%s)\n", 493 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, off, cbWrite, pThis->pszDevice)); 494 RTCritSectEnter(&pThis->CritSect); 495 496 /* 497 * Check the state. 498 */ 499 int rc; 500 if (!pThis->fReadOnly) 501 { 502 if (pThis->fMediaPresent) 503 { 504 void *pvBuf; 505 rc = drvHostBaseBufferRetain(pThis, pReq, cbWrite, true, &pvBuf); 506 if (RT_SUCCESS(rc)) 507 { 508 Log2(("%s-%d: drvHostBaseIoReqWrite: off=%#llx cbWrite=%#x\n" 509 "%16.*Rhxd\n", 510 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, off, cbWrite, cbWrite, pvBuf)); 511 /* 512 * Seek and write. 513 */ 514 rc = drvHostBaseWriteOs(pThis, off, pvBuf, cbWrite); 515 if (RT_FAILURE(rc)) 516 Log(("%s-%d: drvHostBaseIoReqWrite: drvHostBaseWriteOs(%#llx, %p, %#x) -> %Rrc ('%s')\n", 517 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, 518 off, pvBuf, cbWrite, rc, pThis->pszDevice)); 519 520 rc = drvHostBaseBufferRelease(pThis, pReq, cbWrite, true, pvBuf); 521 } 522 } 523 else 524 rc = VERR_MEDIA_NOT_PRESENT; 525 } 526 else 527 rc = VERR_WRITE_PROTECT; 528 529 RTCritSectLeave(&pThis->CritSect); 530 LogFlow(("%s-%d: drvHostBaseIoReqWrite: returns %Rrc\n", pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, rc)); 531 return rc; 532 } 533 534 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqFlush} */ 535 static DECLCALLBACK(int) drvHostBaseIoReqFlush(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq) 536 { 537 RT_NOREF1(hIoReq); 538 539 int rc; 540 PDRVHOSTBASE pThis = RT_FROM_MEMBER(pInterface, DRVHOSTBASE, IMediaEx); 541 LogFlow(("%s-%d: drvHostBaseIoReqFlush: (%s)\n", 542 pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, pThis->pszDevice)); 543 RTCritSectEnter(&pThis->CritSect); 544 545 if (pThis->fMediaPresent) 546 rc = drvHostBaseFlushOs(pThis); 547 else 548 rc = VERR_MEDIA_NOT_PRESENT; 549 550 RTCritSectLeave(&pThis->CritSect); 551 LogFlow(("%s-%d: drvHostBaseFlush: returns %Rrc\n", pThis->pDrvIns->pReg->szName, pThis->pDrvIns->iInstance, rc)); 552 return rc; 553 } 554 555 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqDiscard} */ 556 static DECLCALLBACK(int) drvHostBaseIoReqDiscard(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, unsigned cRangesMax) 557 { 558 RT_NOREF3(pInterface, hIoReq, cRangesMax); 559 return VERR_NOT_SUPPORTED; 560 } 561 562 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqGetActiveCount} */ 563 static DECLCALLBACK(uint32_t) drvHostBaseIoReqGetActiveCount(PPDMIMEDIAEX pInterface) 564 { 565 RT_NOREF1(pInterface); 566 return 0; 567 } 568 569 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqGetSuspendedCount} */ 570 static DECLCALLBACK(uint32_t) drvHostBaseIoReqGetSuspendedCount(PPDMIMEDIAEX pInterface) 571 { 572 RT_NOREF1(pInterface); 573 return 0; 574 } 575 576 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqQuerySuspendedStart} */ 577 static DECLCALLBACK(int) drvHostBaseIoReqQuerySuspendedStart(PPDMIMEDIAEX pInterface, PPDMMEDIAEXIOREQ phIoReq, void **ppvIoReqAlloc) 578 { 579 RT_NOREF3(pInterface, phIoReq, ppvIoReqAlloc); 580 return VERR_NOT_IMPLEMENTED; 581 } 582 583 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqQuerySuspendedNext} */ 584 static DECLCALLBACK(int) drvHostBaseIoReqQuerySuspendedNext(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, 585 PPDMMEDIAEXIOREQ phIoReqNext, void **ppvIoReqAllocNext) 586 { 587 RT_NOREF4(pInterface, hIoReq, phIoReqNext, ppvIoReqAllocNext); 588 return VERR_NOT_IMPLEMENTED; 589 } 590 591 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqSuspendedSave} */ 592 static DECLCALLBACK(int) drvHostBaseIoReqSuspendedSave(PPDMIMEDIAEX pInterface, PSSMHANDLE pSSM, PDMMEDIAEXIOREQ hIoReq) 593 { 594 RT_NOREF3(pInterface, pSSM, hIoReq); 595 return VERR_NOT_IMPLEMENTED; 596 } 597 598 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqSuspendedLoad} */ 599 static DECLCALLBACK(int) drvHostBaseIoReqSuspendedLoad(PPDMIMEDIAEX pInterface, PSSMHANDLE pSSM, PDMMEDIAEXIOREQ hIoReq) 600 { 601 RT_NOREF3(pInterface, pSSM, hIoReq); 602 return VERR_NOT_IMPLEMENTED; 305 603 } 306 604 … … 442 740 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia); 443 741 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUNT, &pThis->IMount); 742 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAEX, pThis->pDrvMediaExPort ? &pThis->IMediaEx : NULL); 444 743 return NULL; 445 744 } … … 683 982 RTStrFree(pThis->pszDeviceOpen); 684 983 pThis->pszDeviceOpen = NULL; 984 } 985 986 if (pThis->pvBuf) 987 { 988 RTMemFree(pThis->pvBuf); 989 pThis->pvBuf = NULL; 990 pThis->cbBuf = 0; 685 991 } 686 992 … … 740 1046 pThis->IMedia.pfnBiosIsVisible = drvHostBaseIsVisible; 741 1047 1048 /* IMediaEx */ 1049 pThis->IMediaEx.pfnQueryFeatures = drvHostBaseQueryFeatures; 1050 pThis->IMediaEx.pfnIoReqAllocSizeSet = drvHostBaseIoReqAllocSizeSet; 1051 pThis->IMediaEx.pfnIoReqAlloc = drvHostBaseIoReqAlloc; 1052 pThis->IMediaEx.pfnIoReqFree = drvHostBaseIoReqFree; 1053 pThis->IMediaEx.pfnIoReqQueryResidual = drvHostBaseIoReqQueryResidual; 1054 pThis->IMediaEx.pfnIoReqCancelAll = drvHostBaseIoReqCancelAll; 1055 pThis->IMediaEx.pfnIoReqCancel = drvHostBaseIoReqCancel; 1056 pThis->IMediaEx.pfnIoReqRead = drvHostBaseIoReqRead; 1057 pThis->IMediaEx.pfnIoReqWrite = drvHostBaseIoReqWrite; 1058 pThis->IMediaEx.pfnIoReqFlush = drvHostBaseIoReqFlush; 1059 pThis->IMediaEx.pfnIoReqDiscard = drvHostBaseIoReqDiscard; 1060 pThis->IMediaEx.pfnIoReqGetActiveCount = drvHostBaseIoReqGetActiveCount; 1061 pThis->IMediaEx.pfnIoReqGetSuspendedCount = drvHostBaseIoReqGetSuspendedCount; 1062 pThis->IMediaEx.pfnIoReqQuerySuspendedStart = drvHostBaseIoReqQuerySuspendedStart; 1063 pThis->IMediaEx.pfnIoReqQuerySuspendedNext = drvHostBaseIoReqQuerySuspendedNext; 1064 pThis->IMediaEx.pfnIoReqSuspendedSave = drvHostBaseIoReqSuspendedSave; 1065 pThis->IMediaEx.pfnIoReqSuspendedLoad = drvHostBaseIoReqSuspendedLoad; 1066 742 1067 /* IMount. */ 743 1068 pThis->IMount.pfnUnmount = drvHostBaseUnmount; … … 756 1081 757 1082 /* 758 * Get the I BlockPort & IMountNotify interfaces of the above driver/device.1083 * Get the IMediaPort & IMountNotify interfaces of the above driver/device. 759 1084 */ 760 1085 pThis->pDrvMediaPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAPORT); … … 764 1089 return VERR_PDM_MISSING_INTERFACE_ABOVE; 765 1090 } 1091 pThis->pDrvMediaExPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAEXPORT); 766 1092 pThis->pDrvMountNotify = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMOUNTNOTIFY); 767 1093 -
trunk/src/VBox/Devices/Storage/DrvHostBase.h
r64316 r64320 65 65 RTUUID Uuid; 66 66 67 /** Pointer to the blockport interface above us. */67 /** Pointer to the media port interface above us. */ 68 68 PPDMIMEDIAPORT pDrvMediaPort; 69 /** Pointer to the extended media port interface above us. */ 70 PPDMIMEDIAEXPORT pDrvMediaExPort; 69 71 /** Pointer to the mount notify interface above us. */ 70 72 PPDMIMOUNTNOTIFY pDrvMountNotify; 71 73 /** Our media interface. */ 72 74 PDMIMEDIA IMedia; 75 /** Our extended media interface. */ 76 PDMIMEDIAEX IMediaEx; 73 77 /** Our mountable interface. */ 74 78 PDMIMOUNT IMount; … … 96 100 PDMMEDIAGEOMETRY LCHSGeometry; 97 101 102 /** Pointer to the current buffer holding data. */ 103 void *pvBuf; 104 /** Size of the buffer. */ 105 size_t cbBuf; 106 /** Size of the I/O request to allocate. */ 107 size_t cbIoReqAlloc; 108 98 109 /** 99 110 * Performs the locking / unlocking of the device. … … 116 127 } DRVHOSTBASE; 117 128 129 130 /** 131 * Request structure fo a request. 132 */ 133 typedef struct DRVHOSTBASEREQ 134 { 135 /** Start of the request data for the device above us. */ 136 uint8_t abAlloc[1]; 137 } DRVHOSTBASEREQ; 138 /** Pointer to a request structure. */ 139 typedef DRVHOSTBASEREQ *PDRVHOSTBASEREQ; 118 140 119 141 DECLHIDDEN(int) DRVHostBaseInit(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, const char *pszCfgValid, PDMMEDIATYPE enmType); … … 138 160 DECLHIDDEN(void) drvHostBaseDestructOs(PDRVHOSTBASE pThis); 139 161 162 DECLHIDDEN(int) drvHostBaseBufferRetain(PDRVHOSTBASE pThis, PDRVHOSTBASEREQ pReq, size_t cbBuf, bool fWrite, void **ppvBuf); 163 DECLHIDDEN(int) drvHostBaseBufferRelease(PDRVHOSTBASE pThis, PDRVHOSTBASEREQ pReq, size_t cbBuf, bool fWrite, void *pvBuf); 164 140 165 RT_C_DECLS_END 141 166 -
trunk/src/VBox/Devices/Storage/DrvHostDVD.cpp
r64316 r64320 21 21 *********************************************************************************************************************************/ 22 22 #define LOG_GROUP LOG_GROUP_DRV_HOST_DVD 23 #if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)24 # define USE_MEDIA_POLLING25 #endif26 27 #if defined(RT_OS_SOLARIS) && defined(VBOX_WITH_SUID_WRAPPER)28 # include <auth_attr.h>29 #endif30 31 23 #include <iprt/asm.h> 32 24 #include <VBox/vmm/pdmdrv.h> … … 42 34 #include "VBoxDD.h" 43 35 #include "DrvHostBase.h" 44 36 #include "ATAPIPassthrough.h" 37 38 /** 39 * Host DVD driver instance data. 40 */ 41 typedef struct DRVHOSTDVD 42 { 43 /** Base drivr data. */ 44 DRVHOSTBASE Core; 45 /** The current tracklist of the loaded medium if passthrough is used. */ 46 PTRACKLIST pTrackList; 47 } DRVHOSTDVD; 48 /** Pointer to the host DVD driver instance data. */ 49 typedef DRVHOSTDVD *PDRVHOSTDVD; 45 50 46 51 /********************************************************************************************************************************* … … 48 53 *********************************************************************************************************************************/ 49 54 55 56 static PDMMEDIATXDIR drvHostDvdGetTxDirFromCmd(uint8_t bCdb) 57 { 58 PDMMEDIATXDIR enmTxDir = PDMMEDIATXDIR_NONE; 59 60 switch (bCdb) 61 { 62 case SCSI_BLANK: 63 case SCSI_CLOSE_TRACK_SESSION: 64 case SCSI_LOAD_UNLOAD_MEDIUM: 65 case SCSI_PAUSE_RESUME: 66 case SCSI_PLAY_AUDIO_10: 67 case SCSI_PLAY_AUDIO_12: 68 case SCSI_PLAY_AUDIO_MSF: 69 case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL: 70 case SCSI_RESERVE_TRACK: 71 case SCSI_SCAN: 72 case SCSI_SEEK_10: 73 case SCSI_REPAIR_TRACK: 74 case SCSI_SET_CD_SPEED: 75 case SCSI_SET_READ_AHEAD: 76 case SCSI_START_STOP_UNIT: 77 case SCSI_STOP_PLAY_SCAN: 78 case SCSI_SYNCHRONIZE_CACHE: 79 case SCSI_TEST_UNIT_READY: 80 case SCSI_VERIFY_10: 81 enmTxDir = PDMMEDIATXDIR_NONE; 82 break; 83 case SCSI_SET_STREAMING: 84 case SCSI_ERASE_10: 85 case SCSI_FORMAT_UNIT: 86 case SCSI_MODE_SELECT_10: 87 case SCSI_SEND_CUE_SHEET: 88 case SCSI_SEND_DVD_STRUCTURE: 89 case SCSI_SEND_EVENT: 90 case SCSI_SEND_KEY: 91 case SCSI_SEND_OPC_INFORMATION: 92 case SCSI_WRITE_10: 93 case SCSI_WRITE_AND_VERIFY_10: 94 case SCSI_WRITE_12: 95 enmTxDir = PDMMEDIATXDIR_TO_DEVICE; 96 break; 97 case SCSI_GET_CONFIGURATION: 98 case SCSI_GET_EVENT_STATUS_NOTIFICATION: 99 case SCSI_GET_PERFORMANCE: 100 case SCSI_INQUIRY: 101 case SCSI_MECHANISM_STATUS: 102 case SCSI_MODE_SENSE_10: 103 case SCSI_READ_10: 104 case SCSI_READ_12: 105 case SCSI_READ_BUFFER: 106 case SCSI_READ_BUFFER_CAPACITY: 107 case SCSI_READ_CAPACITY: 108 case SCSI_READ_CD: 109 case SCSI_READ_CD_MSF: 110 case SCSI_READ_DISC_INFORMATION: 111 case SCSI_READ_DVD_STRUCTURE: 112 case SCSI_READ_FORMAT_CAPACITIES: 113 case SCSI_READ_SUBCHANNEL: 114 case SCSI_READ_TOC_PMA_ATIP: 115 case SCSI_READ_TRACK_INFORMATION: 116 case SCSI_REPORT_KEY: 117 case SCSI_REQUEST_SENSE: 118 case SCSI_REPORT_LUNS: /* Not part of MMC-3, but used by Windows. */ 119 enmTxDir = PDMMEDIATXDIR_FROM_DEVICE; 120 break; 121 122 case SCSI_WRITE_BUFFER: 123 #if 0 124 switch (pbPacket[1] & 0x1f) 125 { 126 case 0x04: /* download microcode */ 127 case 0x05: /* download microcode and save */ 128 case 0x06: /* download microcode with offsets */ 129 case 0x07: /* download microcode with offsets and save */ 130 case 0x0e: /* download microcode with offsets and defer activation */ 131 case 0x0f: /* activate deferred microcode */ 132 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough command attempted to update firmware, blocked\n", s->iLUN)); 133 atapiR3CmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET); 134 break; 135 default: 136 enmTxDir = PDMMEDIATXDIR_TO_DEVICE; 137 break; 138 } 139 #endif 140 break; 141 case SCSI_REZERO_UNIT: 142 /* Obsolete command used by cdrecord. What else would one expect? 143 * This command is not sent to the drive, it is handled internally, 144 * as the Linux kernel doesn't like it (message "scsi: unknown 145 * opcode 0x01" in syslog) and replies with a sense code of 0, 146 * which sends cdrecord to an endless loop. */ 147 //atapiR3CmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE); 148 break; 149 default: 150 LogRel(("HostDVD: passthrough unimplemented for command %#x\n", bCdb)); 151 //atapiR3CmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE); 152 break; 153 } 154 155 return enmTxDir; 156 } 50 157 51 158 /** … … 74 181 LogFlow(("%s: cmd[0]=%#04x txdir=%d pcbBuf=%d timeout=%d\n", __FUNCTION__, pbCmd[0], enmTxDir, *pcbBuf, cTimeoutMillies)); 75 182 183 RTCritSectEnter(&pThis->CritSect); 76 184 /* 77 185 * Pass the request on to the internal scsi command interface. … … 92 200 Log2((" event %#02x %#02x %#02x %#02x\n", pbBuf[4], pbBuf[5], pbBuf[6], pbBuf[7])); 93 201 } 202 RTCritSectLeave(&pThis->CritSect); 94 203 95 204 LogFlow(("%s: rc=%Rrc\n", __FUNCTION__, rc)); … … 98 207 99 208 209 /** @interface_method_impl{PDMIMEDIAEX,pfnIoReqSendScsiCmd} */ 210 static DECLCALLBACK(int) drvHostDvdIoReqSendScsiCmd(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, uint32_t uLun, 211 const uint8_t *pbCdb, size_t cbCdb, PDMMEDIAEXIOREQSCSITXDIR enmTxDir, 212 size_t cbBuf, uint8_t *pabSense, size_t cbSense, uint8_t *pu8ScsiSts, 213 uint32_t cTimeoutMillies) 214 { 215 RT_NOREF2(uLun, cTimeoutMillies); 216 217 PDRVHOSTBASE pThis = RT_FROM_MEMBER(pInterface, DRVHOSTBASE, IMediaEx); 218 PDRVHOSTBASEREQ pReq = (PDRVHOSTBASEREQ)hIoReq; 219 int rc = VINF_SUCCESS; 220 void *pvBuf = NULL; 221 222 LogFlow(("%s: pbCdb[0]=%#04x enmTxDir=%d cbBuf=%zu timeout=%u\n", __FUNCTION__, pbCdb[0], enmTxDir, cbBuf, cTimeoutMillies)); 223 224 RTCritSectEnter(&pThis->CritSect); 225 if (cbBuf) 226 { 227 bool fWrite = (enmTxDir == PDMMEDIAEXIOREQSCSITXDIR_UNKNOWN || enmTxDir == PDMMEDIAEXIOREQSCSITXDIR_TO_DEVICE); 228 rc = drvHostBaseBufferRetain(pThis, pReq, cbBuf, fWrite, &pvBuf); 229 } 230 231 if (RT_SUCCESS(rc)) 232 { 233 uint32_t cbBufTmp = (uint32_t)cbBuf; 234 PDMMEDIATXDIR enmMediaTxDir = PDMMEDIATXDIR_NONE; 235 /* 236 * Pass the request on to the internal scsi command interface. 237 * The command seems to be 12 bytes long, the docs a bit copy&pasty on the command length point... 238 */ 239 if (enmTxDir == PDMMEDIAEXIOREQSCSITXDIR_UNKNOWN || enmTxDir == PDMMEDIAEXIOREQSCSITXDIR_FROM_DEVICE) 240 memset(pvBuf, '\0', cbBuf); /* we got read size, but zero it anyway. */ 241 242 if (cbBuf) 243 { 244 switch (enmTxDir) 245 { 246 case PDMMEDIAEXIOREQSCSITXDIR_FROM_DEVICE: 247 enmMediaTxDir = PDMMEDIATXDIR_FROM_DEVICE; 248 break; 249 case PDMMEDIAEXIOREQSCSITXDIR_TO_DEVICE: 250 enmMediaTxDir = PDMMEDIATXDIR_TO_DEVICE; 251 break; 252 case PDMMEDIAEXIOREQSCSITXDIR_UNKNOWN: 253 enmMediaTxDir = drvHostDvdGetTxDirFromCmd(pbCdb[0]); 254 break; 255 case PDMMEDIAEXIOREQSCSITXDIR_NONE: 256 default: 257 enmMediaTxDir = PDMMEDIATXDIR_NONE; 258 break; 259 } 260 } 261 262 rc = drvHostBaseScsiCmdOs(pThis, pbCdb, cbCdb, enmMediaTxDir, pvBuf, &cbBufTmp, pabSense, cbSense, cTimeoutMillies); 263 if (rc == VERR_UNRESOLVED_ERROR) 264 { 265 /* sense information set */ 266 rc = VERR_DEV_IO_ERROR; 267 *pu8ScsiSts = SCSI_STATUS_CHECK_CONDITION; 268 } 269 270 if (pbCdb[0] == SCSI_GET_EVENT_STATUS_NOTIFICATION) 271 { 272 uint8_t *pbBuf = (uint8_t*)pvBuf; 273 Log2(("Event Status Notification class=%#02x supported classes=%#02x\n", pbBuf[2], pbBuf[3])); 274 if (RT_BE2H_U16(*(uint16_t*)pbBuf) >= 6) 275 Log2((" event %#02x %#02x %#02x %#02x\n", pbBuf[4], pbBuf[5], pbBuf[6], pbBuf[7])); 276 } 277 278 if (cbBuf) 279 { 280 bool fWrite = (enmTxDir == PDMMEDIAEXIOREQSCSITXDIR_UNKNOWN || enmTxDir == PDMMEDIAEXIOREQSCSITXDIR_TO_DEVICE); 281 rc = drvHostBaseBufferRelease(pThis, pReq, cbBuf, fWrite, pvBuf); 282 } 283 } 284 RTCritSectLeave(&pThis->CritSect); 285 286 LogFlow(("%s: rc=%Rrc\n", __FUNCTION__, rc)); 287 return rc; 288 } 289 290 100 291 /* -=-=-=-=- driver interface -=-=-=-=- */ 101 292 293 294 /** @interface_method_impl{PDMDRVREG,pfnDestruct} */ 295 static DECLCALLBACK(void) drvHostDvdDestruct(PPDMDRVINS pDrvIns) 296 { 297 PDRVHOSTDVD pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTDVD); 298 299 if (pThis->pTrackList) 300 { 301 ATAPIPassthroughTrackListDestroy(pThis->pTrackList); 302 pThis->pTrackList = NULL; 303 } 304 305 DRVHostBaseDestruct(pDrvIns); 306 } 102 307 103 308 /** … … 109 314 { 110 315 RT_NOREF(fFlags); 111 PDRVHOST BASE pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTBASE);316 PDRVHOSTDVD pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTDVD); 112 317 LogFlow(("drvHostDvdConstruct: iInstance=%d\n", pDrvIns->iInstance)); 113 318 … … 116 321 if (RT_SUCCESS(rc) && fPassthrough) 117 322 { 118 pThis->IMedia.pfnSendCmd = drvHostDvdSendCmd; 323 pThis->Core.IMedia.pfnSendCmd = drvHostDvdSendCmd; 324 pThis->Core.IMediaEx.pfnIoReqSendScsiCmd = drvHostDvdIoReqSendScsiCmd; 119 325 /* Passthrough requires opening the device in R/W mode. */ 120 pThis-> fReadOnlyConfig = false;121 } 122 123 pThis-> pfnDoLock = drvHostDvdDoLock;326 pThis->Core.fReadOnlyConfig = false; 327 } 328 329 pThis->Core.pfnDoLock = drvHostDvdDoLock; 124 330 125 331 /* … … 155 361 ~0U, 156 362 /* cbInstance */ 157 sizeof(DRVHOST BASE),363 sizeof(DRVHOSTDVD), 158 364 /* pfnConstruct */ 159 365 drvHostDvdConstruct, 160 366 /* pfnDestruct */ 161 DRVHostBaseDestruct,367 drvHostDvdDestruct, 162 368 /* pfnRelocate */ 163 369 NULL,
Note:
See TracChangeset
for help on using the changeset viewer.