Changeset 81675 in vbox
- Timestamp:
- Nov 5, 2019 4:13:34 PM (5 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp
r81663 r81675 338 338 339 339 /** 340 * Worker thread context 340 * Worker thread context, shared state. 341 341 */ 342 342 typedef struct VIRTIOSCSIWORKER 343 343 { 344 SUPSEMEVENT hEvtProcess; /**< handle of associated sleep/wake-up semaphore */ 345 } VIRTIOSCSIWORKER; 346 /** Pointer to a VirtIO SCSI worker. */ 347 typedef VIRTIOSCSIWORKER *PVIRTIOSCSIWORKER; 348 349 /** 350 * Worker thread context, ring-3 state. 351 */ 352 typedef struct VIRTIOSCSIWORKERR3 353 { 344 354 R3PTRTYPE(PPDMTHREAD) pThread; /**< pointer to worker thread's handle */ 345 SUPSEMEVENT hEvtProcess; /**< handle of associated sleep/wake-up semaphore */ 346 bool fSleeping; /**< Flags whether worker thread is sleeping or not */ 347 bool fNotified; /**< Flags whether worker thread notified */ 348 } VIRTIOSCSIWORKER; 349 typedef VIRTIOSCSIWORKER *PVIRTIOSCSIWORKER; 355 bool volatile fSleeping; /**< Flags whether worker thread is sleeping or not */ 356 bool volatile fNotified; /**< Flags whether worker thread notified */ 357 } VIRTIOSCSIWORKERR3; 358 /** Pointer to a VirtIO SCSI worker. */ 359 typedef VIRTIOSCSIWORKERR3 *PVIRTIOSCSIWORKERR3; 360 350 361 351 362 /** … … 354 365 typedef struct VIRTIOSCSITARGET 355 366 { 356 /** Pointer to PCI device that owns this target instance. - R3 pointer*/357 R3PTRTYPE(struct VIRTIOSCSI *) pVirtioScsi;367 /** The ring-3 device instance so we can easily get our bearings. */ 368 PPDMDEVINSR3 pDevIns; 358 369 359 370 /** Pointer to attached driver's base interface. */ … … 361 372 362 373 /** Target number (PDM LUN) */ 363 RTUINTiTarget;374 uint32_t iTarget; 364 375 365 376 /** Target Description */ 366 char *pszTargetName;377 R3PTRTYPE(char *) pszTargetName; 367 378 368 379 /** Target base interface. */ … … 407 418 408 419 /** 409 * PDM instance data (state) for VirtIO Host SCSI device420 * VirtIO Host SCSI device state, shared edition. 410 421 * 411 * @extends PDMPCIDEV422 * @extends VIRTIOSTATE 412 423 */ 413 424 typedef struct VIRTIOSCSI … … 417 428 418 429 bool fBootable; 419 bool afPadding [3];430 bool afPadding0[3]; 420 431 421 432 /** Number of targets in paTargetInstances. */ 422 433 uint32_t cTargets; 434 435 /** Per device-bound virtq worker-thread contexts (eventq slot unused) */ 436 VIRTIOSCSIWORKER aWorkers[VIRTIOSCSI_QUEUE_CNT]; 437 438 /** Instance name */ 439 char szInstance[16]; 440 441 /** Device-specific spec-based VirtIO queuenames */ 442 char aszQueueNames[VIRTIOSCSI_QUEUE_CNT][VIRTIO_MAX_QUEUE_NAME_SIZE]; 443 444 /** Track which VirtIO queues we've attached to */ 445 bool afQueueAttached[VIRTIOSCSI_QUEUE_CNT]; 446 447 /** Set if events missed due to lack of bufs avail on eventq */ 448 bool fEventsMissed; 449 450 /** True if PDMDevHlpAsyncNotificationCompleted should be called when port goes idle 451 * @todo r=bird: What's this for exactly? It's not referenced anywhere... */ 452 bool volatile fSignalIdle; 453 /** Explicit alignment padding. */ 454 bool afPadding1[2]; 455 456 /** Mask of VirtIO Async Event types this device will deliver */ 457 uint32_t fAsyncEvtsEnabled; 458 459 /** Total number of requests active across all targets */ 460 volatile uint32_t cActiveReqs; 461 462 /** Events the guest has subscribed to get notifications of */ 463 uint32_t fSubscribedEvents; 464 465 /** VirtIO Host SCSI device runtime configuration parameters */ 466 VIRTIOSCSI_CONFIG_T virtioScsiConfig; 467 468 /** True if the guest/driver and VirtIO framework are in the ready state */ 469 uint32_t fVirtioReady; 470 471 /** True if VIRTIO_SCSI_F_T10_PI was negotiated */ 472 uint32_t fHasT10pi; 473 474 /** True if VIRTIO_SCSI_F_T10_PI was negotiated */ 475 uint32_t fHasHotplug; 476 477 /** True if VIRTIO_SCSI_F_T10_PI was negotiated */ 478 uint32_t fHasInOutBufs; 479 480 /** True if VIRTIO_SCSI_F_T10_PI was negotiated */ 481 uint32_t fHasLunChange; 482 483 /** True if in the process of resetting */ 484 uint32_t fResetting; 485 486 } VIRTIOSCSI; 487 /** Pointer to the shared state of the VirtIO Host SCSI device. */ 488 typedef VIRTIOSCSI *PVIRTIOSCSI; 489 490 491 /** 492 * VirtIO Host SCSI device state, ring-3 edition. 493 * 494 * @extends VIRTIOSTATER3 495 */ 496 typedef struct VIRTIOSCSIR3 497 { 498 /** The virtio ring-3 state. */ 499 VIRTIOSTATER3 Virtio; 500 423 501 /** Array of per-target data. */ 424 502 R3PTRTYPE(PVIRTIOSCSITARGET) paTargetInstances; 425 #if HC_ARCH_BITS == 32426 RTR3PTR R3PtrPadding0;427 #endif428 503 429 504 /** Per device-bound virtq worker-thread contexts (eventq slot unused) */ 430 VIRTIOSCSIWORKER aWorkers[VIRTIOSCSI_QUEUE_CNT]; 431 432 /** Instance name */ 433 char szInstance[16]; 434 435 /** Device-specific spec-based VirtIO queuenames */ 436 char aszQueueNames[VIRTIOSCSI_QUEUE_CNT][VIRTIO_MAX_QUEUE_NAME_SIZE]; 437 438 /** Track which VirtIO queues we've attached to */ 439 bool afQueueAttached[VIRTIOSCSI_QUEUE_CNT]; 505 VIRTIOSCSIWORKERR3 aWorkers[VIRTIOSCSI_QUEUE_CNT]; 440 506 441 507 /** Device base interface. */ 442 508 PDMIBASE IBase; 443 509 444 /** Pointer to the device instance. - R3 ptr. */ 445 PPDMDEVINSR3 pDevInsR3; 446 447 /** Pointer to the device instance. - R0 ptr. */ 448 PPDMDEVINSR0 pDevInsR0; 449 450 /** Pointer to the device instance. - RC ptr. */ 451 PPDMDEVINSRC pDevInsRC; 510 /** Pointer to the device instance. 511 * @note Only used in interface callbacks. */ 512 PPDMDEVINSR3 pDevIns; 452 513 453 514 /** Status Target: LEDs port interface. */ … … 462 523 /** Queue to send tasks to R3. - HC ptr */ 463 524 R3PTRTYPE(PPDMQUEUE) pNotifierQueueR3; 464 465 /** The support driver session handle. */466 R3R0PTRTYPE(PSUPDRVSESSION) pSupDrvSession;467 468 /** Mask of VirtIO Async Event types this device will deliver */469 uint32_t fAsyncEvtsEnabled;470 471 /** Total number of requests active across all targets */472 volatile uint32_t cActiveReqs;473 474 /** True if PDMDevHlpAsyncNotificationCompleted should be called when port goes idle */475 bool volatile fSignalIdle;476 477 /** Events the guest has subscribed to get notifications of */478 uint32_t fSubscribedEvents;479 480 /** Set if events missed due to lack of bufs avail on eventq */481 bool fEventsMissed;482 483 /** VirtIO Host SCSI device runtime configuration parameters */484 VIRTIOSCSI_CONFIG_T virtioScsiConfig;485 486 /** True if the guest/driver and VirtIO framework are in the ready state */487 uint32_t fVirtioReady;488 489 /** True if VIRTIO_SCSI_F_T10_PI was negotiated */490 uint32_t fHasT10pi;491 492 /** True if VIRTIO_SCSI_F_T10_PI was negotiated */493 uint32_t fHasHotplug;494 495 /** True if VIRTIO_SCSI_F_T10_PI was negotiated */496 uint32_t fHasInOutBufs;497 498 /** True if VIRTIO_SCSI_F_T10_PI was negotiated */499 uint32_t fHasLunChange;500 501 /** True if in the process of resetting */502 uint32_t fResetting;503 525 504 526 /** True if in the process of quiescing I/O */ … … 507 529 VIRTIOSCSIQUIESCINGFOR enmQuiescingFor; 508 530 509 } VIRTIOSCSI, *PVIRTIOSCSI; 531 } VIRTIOSCSIR3; 532 /** Pointer to the ring-3 state of the VirtIO Host SCSI device. */ 533 typedef VIRTIOSCSIR3 *PVIRTIOSCSIR3; 534 535 536 /** 537 * VirtIO Host SCSI device state, ring-0 edition. 538 */ 539 typedef struct VIRTIOSCSIR0 540 { 541 /** The virtio ring-0 state. */ 542 VIRTIOSTATER0 Virtio; 543 } VIRTIOSCSIR0; 544 /** Pointer to the ring-0 state of the VirtIO Host SCSI device. */ 545 typedef VIRTIOSCSIR0 *PVIRTIOSCSIR0; 546 547 548 /** 549 * VirtIO Host SCSI device state, raw-mode edition. 550 */ 551 typedef struct VIRTIOSCSIRC 552 { 553 /** The virtio raw-mode state. */ 554 VIRTIOSTATERC Virtio; 555 } VIRTIOSCSIRC; 556 /** Pointer to the ring-0 state of the VirtIO Host SCSI device. */ 557 typedef VIRTIOSCSIRC *PVIRTIOSCSIRC; 558 559 560 /** @typedef VIRTIOSCSICC 561 * The instance data for the current context. */ 562 typedef CTX_SUFF(VIRTIOSCSI) VIRTIOSCSICC; 563 /** @typedef PVIRTIOSCSICC 564 * Pointer to the instance data for the current context. */ 565 typedef CTX_SUFF(PVIRTIOSCSI) PVIRTIOSCSICC; 566 510 567 511 568 /** … … 613 670 #endif /* LOG_ENABLED */ 614 671 615 static int virtioScsiR3SendEvent(P VIRTIOSCSI pThis, uint16_t uTarget, uint32_t uEventType, uint32_t uReason)672 static int virtioScsiR3SendEvent(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget, uint32_t uEventType, uint32_t uReason) 616 673 { 617 674 … … 671 728 } 672 729 673 if (virtioQueueIsEmpty( &pThis->Virtio, EVENTQ_IDX))730 if (virtioQueueIsEmpty(pDevIns, &pThis->Virtio, EVENTQ_IDX)) 674 731 { 675 732 LogFunc(("eventq is empty, events missed (driver didn't preload queue)!\n")); … … 679 736 680 737 PVIRTIO_DESC_CHAIN_T pDescChain; 681 virtioR3QueueGet( &pThis->Virtio, EVENTQ_IDX, &pDescChain, true);738 virtioR3QueueGet(pDevIns, &pThis->Virtio, EVENTQ_IDX, &pDescChain, true); 682 739 683 740 RTSGBUF reqSegBuf; … … 685 742 RTSgBufInit(&reqSegBuf, aReqSegs, RT_ELEMENTS(aReqSegs)); 686 743 687 virtioR3QueuePut( &pThis->Virtio, EVENTQ_IDX, &reqSegBuf, pDescChain, true);688 virtioQueueSync( &pThis->Virtio, EVENTQ_IDX);744 virtioR3QueuePut(pDevIns, &pThis->Virtio, EVENTQ_IDX, &reqSegBuf, pDescChain, true); 745 virtioQueueSync(pDevIns, &pThis->Virtio, EVENTQ_IDX); 689 746 690 747 return VINF_SUCCESS; … … 702 759 * This is called to complete a request immediately 703 760 * 704 * @param pThis PDM driver instance state 761 * @param pDevIns The device instance. 762 * @param pThis VirtIO SCSI shared instance data. 763 * @param pThisCC VirtIO SCSI ring-3 instance data. 705 764 * @param qIdx Queue index 706 765 * @param pDescChain Pointer to pre-processed descriptor chain pulled from virtq … … 710 769 * @returns VBox status code. 711 770 */ 712 static int virtioScsiR3ReqErr(P VIRTIOSCSI pThis, uint16_t qIdx, PVIRTIO_DESC_CHAIN_T pDescChain,713 REQ_RESP_HDR_T *pRespHdr, uint8_t *pbSense)771 static int virtioScsiR3ReqErr(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, uint16_t qIdx, 772 PVIRTIO_DESC_CHAIN_T pDescChain, REQ_RESP_HDR_T *pRespHdr, uint8_t *pbSense) 714 773 { 715 774 uint8_t *pabSenseBuf = (uint8_t *)RTMemAllocZ(pThis->virtioScsiConfig.uSenseSize); … … 735 794 pRespHdr->uResponse = VIRTIOSCSI_S_RESET; 736 795 737 virtioR3QueuePut( &pThis->Virtio, qIdx, &reqSegBuf, pDescChain, true /* fFence */);738 virtioQueueSync( &pThis->Virtio, qIdx);796 virtioR3QueuePut(pDevIns, &pThis->Virtio, qIdx, &reqSegBuf, pDescChain, true /* fFence */); 797 virtioQueueSync(pDevIns, &pThis->Virtio, qIdx); 739 798 740 799 RTMemFree(pabSenseBuf); 741 800 742 if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThis ->fQuiescing)743 PDMDevHlpAsyncNotificationCompleted(p This->CTX_SUFF(pDevIns));801 if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThisCC->fQuiescing) 802 PDMDevHlpAsyncNotificationCompleted(pDevIns); 744 803 745 804 Log2(("---------------------------------------------------------------------------------\n")); … … 779 838 void *pvIoReqAlloc, int rcReq) 780 839 { 781 RT_NOREF(pInterface);782 783 PVIRTIOSCSI REQ pReq = (PVIRTIOSCSIREQ)pvIoReqAlloc;784 PVIRTIOSCSI TARGET pTarget = pReq->pTarget;785 P VIRTIOSCSI pThis = pTarget->pVirtioScsi;786 P PDMIMEDIAEX pIMediaEx = pTarget->pDrvMediaEx;840 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort); 841 PPDMDEVINS pDevIns = pTarget->pDevIns; 842 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 843 PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC); 844 PPDMIMEDIAEX pIMediaEx = pTarget->pDrvMediaEx; 845 PVIRTIOSCSIREQ pReq = (PVIRTIOSCSIREQ)pvIoReqAlloc; 787 846 788 847 size_t cbResidual = 0; … … 866 925 respHdr.uResidual = pReq->cbDataIn; 867 926 868 virtioScsiR3ReqErr(p This, pReq->qIdx, pReq->pDescChain, &respHdr, abSense);927 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, pReq->qIdx, pReq->pDescChain, &respHdr, abSense); 869 928 } 870 929 else … … 891 950 892 951 893 virtioR3QueuePut( &pThis->Virtio, pReq->qIdx, &reqSegBuf, pReq->pDescChain, true /* fFence TBD */);894 virtioQueueSync( &pThis->Virtio, pReq->qIdx);952 virtioR3QueuePut(pDevIns, &pThis->Virtio, pReq->qIdx, &reqSegBuf, pReq->pDescChain, true /* fFence TBD */); 953 virtioQueueSync(pDevIns, &pThis->Virtio, pReq->qIdx); 895 954 896 955 … … 900 959 virtioScsiR3FreeReq(pTarget, pReq); 901 960 902 if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThis ->fQuiescing)903 PDMDevHlpAsyncNotificationCompleted(p This->CTX_SUFF(pDevIns));961 if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThisCC->fQuiescing) 962 PDMDevHlpAsyncNotificationCompleted(pDevIns); 904 963 905 964 return VINF_SUCCESS; … … 914 973 void *pvIoReqAlloc, uint32_t offDst, PRTSGBUF pSgBuf, size_t cbCopy) 915 974 { 975 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort); 976 PPDMDEVINS pDevIns = pTarget->pDevIns; 977 PVIRTIOSCSIREQ pReq = (PVIRTIOSCSIREQ)pvIoReqAlloc; 916 978 RT_NOREF(hIoReq, cbCopy); 917 918 PVIRTIOSCSIREQ pReq = (PVIRTIOSCSIREQ)pvIoReqAlloc;919 979 920 980 if (!pReq->cbDataIn) 921 981 return VINF_SUCCESS; 922 923 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort);924 PVIRTIOSCSI pThis = pTarget->pVirtioScsi;925 982 926 983 AssertReturn(pReq->pDescChain, VERR_INVALID_PARAMETER); … … 942 999 uint64_t dstSgCur = (uint64_t)pSgPhysReturn->pvSegCur; 943 1000 cbCopied = RT_MIN((uint64_t)pSgBuf->cbSegLeft, dstSgLen - (dstSgCur - dstSgStart)); 944 PDMDevHlpPhysWrite(pThis->CTX_SUFF(pDevIns), 945 (RTGCPHYS)pSgPhysReturn->pvSegCur, pSgBuf->pvSegCur, cbCopied); 1001 PDMDevHlpPhysWrite(pDevIns, (RTGCPHYS)pSgPhysReturn->pvSegCur, pSgBuf->pvSegCur, cbCopied); 946 1002 RTSgBufAdvance(pSgBuf, cbCopied); 947 1003 RTSgBufAdvance(pSgPhysReturn, cbCopied); … … 964 1020 void *pvIoReqAlloc, uint32_t offSrc, PRTSGBUF pSgBuf, size_t cbCopy) 965 1021 { 1022 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort); 1023 PPDMDEVINS pDevIns = pTarget->pDevIns; 1024 PVIRTIOSCSIREQ pReq = (PVIRTIOSCSIREQ)pvIoReqAlloc; 966 1025 RT_NOREF(hIoReq, cbCopy); 967 968 PVIRTIOSCSIREQ pReq = (PVIRTIOSCSIREQ)pvIoReqAlloc;969 1026 970 1027 if (!pReq->cbDataOut) 971 1028 return VINF_SUCCESS; 972 973 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort);974 PVIRTIOSCSI pThis = pTarget->pVirtioScsi;975 1029 976 1030 PRTSGBUF pSgPhysSend = pReq->pDescChain->pSgPhysSend; … … 986 1040 uint64_t srcSgCur = (uint64_t)pSgPhysSend->pvSegCur; 987 1041 cbCopied = RT_MIN((uint64_t)pSgBuf->cbSegLeft, srcSgLen - (srcSgCur - srcSgStart)); 988 PDMDevHlpPhysRead(p This->CTX_SUFF(pDevIns),1042 PDMDevHlpPhysRead(pDevIns, 989 1043 (RTGCPHYS)pSgPhysSend->pvSegCur, pSgBuf->pvSegCur, cbCopied); 990 1044 RTSgBufAdvance(pSgBuf, cbCopied); … … 1004 1058 static DECLCALLBACK(void) virtioScsiR3MediumEjected(PPDMIMEDIAEXPORT pInterface) 1005 1059 { 1006 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort); 1007 PVIRTIOSCSI pThis = pTarget->pVirtioScsi; 1060 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort); 1061 PPDMDEVINS pDevIns = pTarget->pDevIns; 1062 PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC); 1063 1008 1064 LogFunc(("LUN %d Ejected!\n", pTarget->iTarget)); 1009 if (pThis ->pMediaNotify)1010 { 1011 int rc = VMR3ReqCallNoWait(PDMDevHlpGetVM(p This->CTX_SUFF(pDevIns)), VMCPUID_ANY,1012 (PFNRT)pThis ->pMediaNotify->pfnEjected, 2,1013 pThis ->pMediaNotify, pTarget->iTarget);1065 if (pThisCC->pMediaNotify) 1066 { 1067 int rc = VMR3ReqCallNoWait(PDMDevHlpGetVM(pDevIns), VMCPUID_ANY, 1068 (PFNRT)pThisCC->pMediaNotify->pfnEjected, 2, 1069 pThisCC->pMediaNotify, pTarget->iTarget); 1014 1070 AssertRC(rc); 1015 1071 } … … 1022 1078 void *pvIoReqAlloc, PDMMEDIAEXIOREQSTATE enmState) 1023 1079 { 1024 RT_NOREF4(pInterface, hIoReq, pvIoReqAlloc, enmState); 1025 PVIRTIOSCSI pThis = RT_FROM_MEMBER(pInterface, VIRTIOSCSI, IBase); 1080 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort); 1081 PPDMDEVINS pDevIns = pTarget->pDevIns; 1082 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 1083 PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC); 1084 RT_NOREF(hIoReq, pvIoReqAlloc); 1026 1085 1027 1086 switch (enmState) … … 1030 1089 { 1031 1090 /* Stop considering this request active */ 1032 if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThis ->fQuiescing)1033 PDMDevHlpAsyncNotificationCompleted(p This->CTX_SUFF(pDevIns));1091 if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThisCC->fQuiescing) 1092 PDMDevHlpAsyncNotificationCompleted(pDevIns); 1034 1093 break; 1035 1094 } … … 1052 1111 * @returns VBox status code (logged by caller). 1053 1112 */ 1054 static int virtioScsiR3ReqSubmit(PVIRTIOSCSI pThis, uint16_t qIdx, PVIRTIO_DESC_CHAIN_T pDescChain) 1113 static int virtioScsiR3ReqSubmit(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, 1114 uint16_t qIdx, PVIRTIO_DESC_CHAIN_T pDescChain) 1055 1115 { 1056 1116 AssertReturn(pDescChain->cbPhysSend, VERR_INVALID_PARAMETER); … … 1069 1129 size_t cbSeg = cb; 1070 1130 RTGCPHYS GCPhys = (RTGCPHYS)RTSgBufGetNextSegment(pDescChain->pSgPhysSend, &cbSeg); 1071 PDMDevHlpPhysRead(p This->CTX_SUFF(pDevIns), GCPhys, pb, cbSeg);1131 PDMDevHlpPhysRead(pDevIns, GCPhys, pb, cbSeg); 1072 1132 pb += cbSeg; 1073 1133 cb -= cbSeg; … … 1076 1136 uint8_t uTarget = pVirtqReq->ReqHdr.abVirtioLun[1]; 1077 1137 uint32_t uScsiLun = (pVirtqReq->ReqHdr.abVirtioLun[2] << 8 | pVirtqReq->ReqHdr.abVirtioLun[3]) & 0x3fff; 1078 PVIRTIOSCSITARGET pTarget = &pThis->paTargetInstances[uTarget];1079 1138 1080 1139 LogFunc(("[%s] (Target: %d LUN: %d) CDB: %.*Rhxs\n", … … 1092 1151 uint32_t cbDataOut = pDescChain->cbPhysSend - uDataOutOff; 1093 1152 uint32_t cbDataIn = pDescChain->cbPhysReturn - uDataInOff; 1153 1094 1154 /* 1095 1155 * Handle submission errors 1096 1156 */ 1097 1098 if (RT_UNLIKELY(pThis->fResetting)) 1157 /** @todo r=bird: RT_UNLIKELY doesn't work everywhere and is deprecated, convert to RT_LIKELY like in the first instance here. */ 1158 if (RT_LIKELY(!pThis->fResetting)) 1159 { /* likely */ } 1160 else 1099 1161 { 1100 1162 Log2Func(("Aborting req submission because reset is in progress\n")); … … 1104 1166 respHdr.uResponse = VIRTIOSCSI_S_RESET; 1105 1167 respHdr.uResidual = cbDataIn + cbDataOut; 1106 virtioScsiR3ReqErr(p This, qIdx, pDescChain, &respHdr, NULL);1168 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, NULL); 1107 1169 RTMemFree(pVirtqReq); 1108 1170 return VINF_SUCCESS; … … 1119 1181 respHdr.uResponse = VIRTIOSCSI_S_OK; 1120 1182 respHdr.uResidual = cbDataOut + cbDataIn; 1121 virtioScsiR3ReqErr(p This, qIdx, pDescChain, &respHdr, abSense);1183 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense); 1122 1184 RTMemFree(pVirtqReq); 1123 1185 return VINF_SUCCESS; 1124 1186 } 1125 if (RT_UNLIKELY(uTarget >= pThis->cTargets || !pTarget->fPresent)) 1187 1188 if (RT_UNLIKELY( uTarget >= pThis->cTargets 1189 || !pThisCC->paTargetInstances[uTarget].fPresent 1190 || !pThisCC->paTargetInstances[uTarget].pDrvMediaEx)) 1126 1191 { 1127 1192 Log2Func(("Error submitting request, target not present!!\n")); … … 1133 1198 respHdr.uResponse = VIRTIOSCSI_S_BAD_TARGET; 1134 1199 respHdr.uResidual = cbDataIn + cbDataOut; 1135 virtioScsiR3ReqErr(p This, qIdx, pDescChain, &respHdr , abSense);1200 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr , abSense); 1136 1201 RTMemFree(pVirtqReq); 1137 1202 return VINF_SUCCESS; 1138 1203 } 1204 PVIRTIOSCSITARGET pTarget = &pThisCC->paTargetInstances[uTarget]; 1205 1139 1206 if (RT_UNLIKELY(cbDataIn && cbDataOut && !pThis->fHasInOutBufs)) /* VirtIO 1.0, 5.6.6.1.1 */ 1140 1207 { … … 1147 1214 respHdr.uResponse = VIRTIOSCSI_S_FAILURE; 1148 1215 respHdr.uResidual = cbDataIn + cbDataOut; 1149 virtioScsiR3ReqErr(p This, qIdx, pDescChain, &respHdr , abSense);1216 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr , abSense); 1150 1217 RTMemFree(pVirtqReq); 1151 1218 return VINF_SUCCESS; … … 1217 1284 respHdr.uResponse = VIRTIOSCSI_S_FAILURE; 1218 1285 respHdr.uResidual = cbDataIn + cbDataOut; 1219 virtioScsiR3ReqErr(p This, qIdx, pDescChain, &respHdr, abSense);1286 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense); 1220 1287 virtioScsiR3FreeReq(pTarget, pReq); 1221 1288 } … … 1229 1296 * 1230 1297 * @returns VBox status code (ignored by the caller). 1231 * @param pThis The device instance data. 1298 * @param pDevIns The device instance. 1299 * @param pThis VirtIO SCSI shared instance data. 1300 * @param pThisCC VirtIO SCSI ring-3 instance data. 1232 1301 * @param qIdx CONTROLQ_IDX 1233 1302 * @param pDescChain Descriptor chain to process. 1234 1303 */ 1235 static int virtioScsiR3Ctrl(PVIRTIOSCSI pThis, uint16_t qIdx, PVIRTIO_DESC_CHAIN_T pDescChain) 1304 static int virtioScsiR3Ctrl(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, 1305 uint16_t qIdx, PVIRTIO_DESC_CHAIN_T pDescChain) 1236 1306 { 1237 1307 uint8_t bResponse = VIRTIOSCSI_S_OK; … … 1262 1332 AssertCompile(sizeof(RTGCPHYS) == sizeof(void *)); /* ASSUMING RTGCPHYS and host pointers are interchangable. (horrible!) */ 1263 1333 RTGCPHYS GCPhys = (RTGCPHYS)RTSgBufGetNextSegment(pDescChain->pSgPhysSend, &cbSeg); 1264 PDMDevHlpPhysRead(p This->CTX_SUFF(pDevIns), GCPhys, pb, cbSeg);1334 PDMDevHlpPhysRead(pDevIns, GCPhys, pb, cbSeg); 1265 1335 pb += cbSeg; 1266 1336 cb -= cbSeg; … … 1289 1359 QUEUENAME(qIdx), uTarget, uScsiLun, virtioGetTMFTypeText(pScsiCtrlUnion->scsiCtrlTmf.uSubtype))); 1290 1360 1291 PVIRTIOSCSITARGET pTarget = NULL; 1292 if (uTarget < pThis->cTargets) 1293 pTarget = &pThis->paTargetInstances[uTarget]; 1294 1295 if (uTarget >= pThis->cTargets || !pTarget->fPresent) 1361 if (uTarget >= pThis->cTargets || !pThisCC->paTargetInstances[uTarget].fPresent) 1296 1362 bResponse = VIRTIOSCSI_S_BAD_TARGET; 1297 1363 else … … 1345 1411 uint32_t uScsiLun = (pScsiCtrlAnQuery->abScsiLun[2] << 8 | pScsiCtrlAnQuery->abScsiLun[3]) & 0x3fff; 1346 1412 1347 PVIRTIOSCSITARGET pTarget = NULL; 1348 if (uTarget < pThis->cTargets) 1349 pTarget = &pThis->paTargetInstances[uTarget]; 1350 1351 if (uTarget >= pThis->cTargets || !pTarget->fPresent) 1413 if (uTarget >= pThis->cTargets || !pThisCC->paTargetInstances[uTarget].fPresent) 1352 1414 bResponse = VIRTIOSCSI_S_BAD_TARGET; 1353 1415 else … … 1395 1457 } 1396 1458 #endif 1397 1398 PVIRTIOSCSITARGET pTarget = NULL; 1399 if (uTarget < pThis->cTargets) 1400 pTarget = &pThis->paTargetInstances[uTarget]; 1401 1402 if (uTarget >= pThis->cTargets || !pTarget->fPresent) 1459 if (uTarget >= pThis->cTargets || !pThisCC->paTargetInstances[uTarget].fPresent) 1403 1460 bResponse = VIRTIOSCSI_S_BAD_TARGET; 1404 1461 else … … 1433 1490 1434 1491 LogFunc(("Response code: %s\n", virtioGetReqRespText(bResponse))); 1435 virtioR3QueuePut( &pThis->Virtio, qIdx, &reqSegBuf, pDescChain, true);1436 virtioQueueSync( &pThis->Virtio, qIdx);1492 virtioR3QueuePut(pDevIns, &pThis->Virtio, qIdx, &reqSegBuf, pDescChain, true); 1493 virtioQueueSync(pDevIns, &pThis->Virtio, qIdx); 1437 1494 1438 1495 return VINF_SUCCESS; … … 1444 1501 static DECLCALLBACK(int) virtioScsiR3WorkerWakeUp(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 1445 1502 { 1446 RT_NOREF(pThread);1447 uint16_t qIdx = ((uint64_t)pThread->pvUser) & 0xffff;1448 1503 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 1449 return SUPSemEventSignal(pThis->pSupDrvSession, pThis->aWorkers[qIdx].hEvtProcess);1504 return PDMDevHlpSUPSemEventSignal(pDevIns, pThis->aWorkers[(uintptr_t)pThread->pvUser].hEvtProcess); 1450 1505 } 1451 1506 … … 1455 1510 static DECLCALLBACK(int) virtioScsiR3WorkerThread(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 1456 1511 { 1457 uint16_t const qIdx = (uint16_t)(uintptr_t)pThread->pvUser; 1458 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 1459 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[qIdx]; 1512 uint16_t const qIdx = (uint16_t)(uintptr_t)pThread->pvUser; 1513 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 1514 PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC); 1515 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[qIdx]; 1516 PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[qIdx]; 1460 1517 1461 1518 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) … … 1464 1521 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 1465 1522 { 1466 if (virtioQueueIsEmpty( &pThis->Virtio, qIdx))1523 if (virtioQueueIsEmpty(pDevIns, &pThis->Virtio, qIdx)) 1467 1524 { 1468 1525 /* Atomic interlocks avoid missing alarm while going to sleep & notifier waking the awoken */ 1469 ASMAtomicWriteBool(&pWorker ->fSleeping, true);1470 bool fNotificationSent = ASMAtomicXchgBool(&pWorker ->fNotified, false);1526 ASMAtomicWriteBool(&pWorkerR3->fSleeping, true); 1527 bool fNotificationSent = ASMAtomicXchgBool(&pWorkerR3->fNotified, false); 1471 1528 if (!fNotificationSent) 1472 1529 { 1473 1530 Log6Func(("%s worker sleeping...\n", QUEUENAME(qIdx))); 1474 Assert(ASMAtomicReadBool(&pWorker ->fSleeping));1475 int rc = SUPSemEventWaitNoResume(pThis->pSupDrvSession, pWorker->hEvtProcess, RT_INDEFINITE_WAIT);1531 Assert(ASMAtomicReadBool(&pWorkerR3->fSleeping)); 1532 int rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pWorker->hEvtProcess, RT_INDEFINITE_WAIT); 1476 1533 AssertLogRelMsgReturn(RT_SUCCESS(rc) || rc == VERR_INTERRUPTED, ("%Rrc\n", rc), rc); 1477 1534 if (RT_UNLIKELY(pThread->enmState != PDMTHREADSTATE_RUNNING)) 1478 1535 return VINF_SUCCESS; 1479 1536 Log6Func(("%s worker woken\n", QUEUENAME(qIdx))); 1480 ASMAtomicWriteBool(&pWorker ->fNotified, false);1537 ASMAtomicWriteBool(&pWorkerR3->fNotified, false); 1481 1538 } 1482 ASMAtomicWriteBool(&pWorker ->fSleeping, false);1539 ASMAtomicWriteBool(&pWorkerR3->fSleeping, false); 1483 1540 } 1484 1541 … … 1488 1545 break; 1489 1546 } 1490 if (!pThis ->fQuiescing)1547 if (!pThisCC->fQuiescing) 1491 1548 { 1492 1549 Log6Func(("fetching next descriptor chain from %s\n", QUEUENAME(qIdx))); 1493 1550 PVIRTIO_DESC_CHAIN_T pDescChain; 1494 int rc = virtioR3QueueGet( &pThis->Virtio, qIdx, &pDescChain, true);1551 int rc = virtioR3QueueGet(pDevIns, &pThis->Virtio, qIdx, &pDescChain, true); 1495 1552 if (rc == VERR_NOT_AVAILABLE) 1496 1553 { … … 1501 1558 AssertRC(rc); 1502 1559 if (qIdx == CONTROLQ_IDX) 1503 virtioScsiR3Ctrl(p This, qIdx, pDescChain);1560 virtioScsiR3Ctrl(pDevIns, pThis, pThisCC, qIdx, pDescChain); 1504 1561 else /* request queue index */ 1505 1562 { 1506 rc = virtioScsiR3ReqSubmit(p This, qIdx, pDescChain);1563 rc = virtioScsiR3ReqSubmit(pDevIns, pThis, pThisCC, qIdx, pDescChain); 1507 1564 if (RT_FAILURE(rc)) 1508 1565 { … … 1520 1577 *********************************************************************************************************************************/ 1521 1578 1522 DECLINLINE(void) virtioScsiR3ReportEventsMissed(P VIRTIOSCSI pThis, uint16_t uTarget)1523 { 1524 virtioScsiR3SendEvent(p This, uTarget, VIRTIOSCSI_T_NO_EVENT | VIRTIOSCSI_T_EVENTS_MISSED, 0);1579 DECLINLINE(void) virtioScsiR3ReportEventsMissed(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget) 1580 { 1581 virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_NO_EVENT | VIRTIOSCSI_T_EVENTS_MISSED, 0); 1525 1582 } 1526 1583 … … 1530 1587 * This effectively removes the SCSI Target/LUN on the guest side 1531 1588 */ 1532 DECLINLINE(void) virtioScsiR3ReportTargetRemoved(P VIRTIOSCSI pThis, uint16_t uTarget)1589 DECLINLINE(void) virtioScsiR3ReportTargetRemoved(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget) 1533 1590 { 1534 1591 if (pThis->fHasHotplug) 1535 virtioScsiR3SendEvent(p This, uTarget, VIRTIOSCSI_T_TRANSPORT_RESET, VIRTIOSCSI_EVT_RESET_REMOVED);1592 virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_TRANSPORT_RESET, VIRTIOSCSI_EVT_RESET_REMOVED); 1536 1593 } 1537 1594 … … 1539 1596 * This effectively adds the SCSI Target/LUN on the guest side 1540 1597 */ 1541 DECLINLINE(void) virtioScsiR3ReportTargetAdded(P VIRTIOSCSI pThis, uint16_t uTarget)1598 DECLINLINE(void) virtioScsiR3ReportTargetAdded(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget) 1542 1599 { 1543 1600 if (pThis->fHasHotplug) 1544 virtioScsiR3SendEvent(p This, uTarget, VIRTIOSCSI_T_TRANSPORT_RESET, VIRTIOSCSI_EVT_RESET_RESCAN);1545 } 1546 1547 DECLINLINE(void) virtioScsiR3ReportTargetReset(P VIRTIOSCSI pThis, uint16_t uTarget)1548 { 1549 virtioScsiR3SendEvent(p This, uTarget, VIRTIOSCSI_T_TRANSPORT_RESET, VIRTIOSCSI_EVT_RESET_HARD);1550 } 1551 1552 DECLINLINE(void) virtioScsiR3ReportOperChange(P VIRTIOSCSI pThis, uint16_t uTarget)1601 virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_TRANSPORT_RESET, VIRTIOSCSI_EVT_RESET_RESCAN); 1602 } 1603 1604 DECLINLINE(void) virtioScsiR3ReportTargetReset(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget) 1605 { 1606 virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_TRANSPORT_RESET, VIRTIOSCSI_EVT_RESET_HARD); 1607 } 1608 1609 DECLINLINE(void) virtioScsiR3ReportOperChange(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget) 1553 1610 { 1554 1611 if (pThis->fSubscribedEvents & VIRTIOSCSI_EVT_ASYNC_OPERATIONAL_CHANGE) 1555 virtioScsiR3SendEvent(p This, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_OPERATIONAL_CHANGE);1556 } 1557 1558 DECLINLINE(void) virtioScsiR3ReportPowerMsg(P VIRTIOSCSI pThis, uint16_t uTarget)1612 virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_OPERATIONAL_CHANGE); 1613 } 1614 1615 DECLINLINE(void) virtioScsiR3ReportPowerMsg(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget) 1559 1616 { 1560 1617 if (pThis->fSubscribedEvents & VIRTIOSCSI_EVT_ASYNC_POWER_MGMT) 1561 virtioScsiR3SendEvent(p This, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_POWER_MGMT);1562 } 1563 1564 DECLINLINE(void) virtioScsiR3ReportExtReq(P VIRTIOSCSI pThis, uint16_t uTarget)1618 virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_POWER_MGMT); 1619 } 1620 1621 DECLINLINE(void) virtioScsiR3ReportExtReq(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget) 1565 1622 { 1566 1623 if (pThis->fSubscribedEvents & VIRTIOSCSI_EVT_ASYNC_EXTERNAL_REQUEST) 1567 virtioScsiR3SendEvent(p This, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_EXTERNAL_REQUEST);1568 } 1569 1570 DECLINLINE(void) virtioScsiR3ReportMediaChange(P VIRTIOSCSI pThis, uint16_t uTarget)1624 virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_EXTERNAL_REQUEST); 1625 } 1626 1627 DECLINLINE(void) virtioScsiR3ReportMediaChange(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget) 1571 1628 { 1572 1629 if (pThis->fSubscribedEvents & VIRTIOSCSI_EVT_ASYNC_MEDIA_CHANGE) 1573 virtioScsiR3SendEvent(p This, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_MEDIA_CHANGE);1574 } 1575 1576 DECLINLINE(void) virtioScsiR3ReportMultiHost(P VIRTIOSCSI pThis, uint16_t uTarget)1630 virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_MEDIA_CHANGE); 1631 } 1632 1633 DECLINLINE(void) virtioScsiR3ReportMultiHost(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget) 1577 1634 { 1578 1635 if (pThis->fSubscribedEvents & VIRTIOSCSI_EVT_ASYNC_MULTI_HOST) 1579 virtioScsiR3SendEvent(p This, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_MULTI_HOST);1580 } 1581 1582 DECLINLINE(void) virtioScsiR3ReportDeviceBusy(P VIRTIOSCSI pThis, uint16_t uTarget)1636 virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_MULTI_HOST); 1637 } 1638 1639 DECLINLINE(void) virtioScsiR3ReportDeviceBusy(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSI pThis, uint16_t uTarget) 1583 1640 { 1584 1641 if (pThis->fSubscribedEvents & VIRTIOSCSI_EVT_ASYNC_DEVICE_BUSY) 1585 virtioScsiR3SendEvent(pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_DEVICE_BUSY); 1586 } 1587 1588 DECLINLINE(void) virtioScsiR3ReportParamChange(PVIRTIOSCSI pThis, uint16_t uTarget, uint32_t uSenseCode, uint32_t uSenseQualifier) 1642 virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_ASYNC_NOTIFY, VIRTIOSCSI_EVT_ASYNC_DEVICE_BUSY); 1643 } 1644 1645 DECLINLINE(void) virtioScsiR3ReportParamChange(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, uint16_t uTarget, 1646 uint32_t uSenseCode, uint32_t uSenseQualifier) 1589 1647 { 1590 1648 uint32_t uReason = uSenseQualifier << 8 | uSenseCode; 1591 virtioScsiR3SendEvent(p This, uTarget, VIRTIOSCSI_T_PARAM_CHANGE, uReason);1649 virtioScsiR3SendEvent(pDevIns, pThis, uTarget, VIRTIOSCSI_T_PARAM_CHANGE, uReason); 1592 1650 1593 1651 } … … 1598 1656 * @callback_method_impl{FNVIRTIOQUEUENOTIFIED} 1599 1657 */ 1600 static DECLCALLBACK(void) virtioScsiR3Notified(PVIRTIOSTATE pVirtio, uint16_t qIdx) 1601 { 1658 static DECLCALLBACK(void) virtioScsiR3Notified(PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC, uint16_t qIdx) 1659 { 1660 PVIRTIOSCSI pThis = RT_FROM_MEMBER(pVirtio, VIRTIOSCSI, Virtio); 1661 PVIRTIOSCSICC pThisCC = RT_FROM_MEMBER(pVirtioCC, VIRTIOSCSICC, Virtio); 1662 PPDMDEVINS pDevIns = pThisCC->pDevIns; 1602 1663 AssertReturnVoid(qIdx < VIRTIOSCSI_QUEUE_CNT); 1603 PVIRTIOSCSI pThis = RT_FROM_MEMBER(pVirtio, VIRTIOSCSI, Virtio);1604 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[qIdx];1605 1606 RTLogFlush(RTLogDefaultInstanceEx(RT_MAKE_U32(0, UINT16_MAX))); 1664 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[qIdx]; 1665 PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[qIdx]; 1666 1667 RTLogFlush(RTLogDefaultInstanceEx(RT_MAKE_U32(0, UINT16_MAX))); /** @todo r=bird: Why? RTLogFlush(NULL) perhaps, and then inside \#ifdef LOG_ENABLED... */ 1607 1668 1608 1669 if (qIdx == CONTROLQ_IDX || IS_REQ_QUEUE(qIdx)) … … 1610 1671 Log6Func(("%s has available data\n", QUEUENAME(qIdx))); 1611 1672 /* Wake queue's worker thread up if sleeping */ 1612 if (!ASMAtomicXchgBool(&pWorker ->fNotified, true))1673 if (!ASMAtomicXchgBool(&pWorkerR3->fNotified, true)) 1613 1674 { 1614 if (ASMAtomicReadBool(&pWorker ->fSleeping))1675 if (ASMAtomicReadBool(&pWorkerR3->fSleeping)) 1615 1676 { 1616 1677 Log6Func(("waking %s worker.\n", QUEUENAME(qIdx))); 1617 int rc = SUPSemEventSignal(pThis->pSupDrvSession, pWorker->hEvtProcess);1678 int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pWorker->hEvtProcess); 1618 1679 AssertRC(rc); 1619 1680 } … … 1624 1685 Log3Func(("Driver queued buffer(s) to %s\n", QUEUENAME(qIdx))); 1625 1686 if (ASMAtomicXchgBool(&pThis->fEventsMissed, false)) 1626 virtioScsiR3ReportEventsMissed(p This, 0);1687 virtioScsiR3ReportEventsMissed(pDevIns, pThis, 0); 1627 1688 } 1628 1689 else … … 1633 1694 * @callback_method_impl{FNVIRTIOSTATUSCHANGED} 1634 1695 */ 1635 static DECLCALLBACK(void) virtioScsiR3StatusChanged(PVIRTIOSTATE pVirtio, uint32_t fVirtioReady) 1636 { 1637 PVIRTIOSCSI pThis = RT_FROM_MEMBER(pVirtio, VIRTIOSCSI, Virtio); 1696 static DECLCALLBACK(void) virtioScsiR3StatusChanged(PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC, uint32_t fVirtioReady) 1697 { 1698 PVIRTIOSCSI pThis = RT_FROM_MEMBER(pVirtio, VIRTIOSCSI, Virtio); 1699 PVIRTIOSCSICC pThisCC = RT_FROM_MEMBER(pVirtioCC, VIRTIOSCSICC, Virtio); 1638 1700 1639 1701 pThis->fVirtioReady = fVirtioReady; … … 1647 1709 pThis->fHasInOutBufs = fFeatures & VIRTIO_SCSI_F_INOUT; 1648 1710 pThis->fHasLunChange = fFeatures & VIRTIO_SCSI_F_CHANGE; 1649 pThis->fQuiescing = false;1650 1711 pThis->fResetting = false; 1651 1652 for (int i = 0; i < VIRTIOSCSI_QUEUE_CNT; i++) 1712 pThisCC->fQuiescing = false; 1713 1714 for (unsigned i = 0; i < VIRTIOSCSI_QUEUE_CNT; i++) 1653 1715 pThis->afQueueAttached[i] = true; 1654 1716 } … … 1656 1718 { 1657 1719 LogFunc(("VirtIO is resetting\n")); 1658 for ( inti = 0; i < VIRTIOSCSI_QUEUE_CNT; i++)1720 for (unsigned i = 0; i < VIRTIOSCSI_QUEUE_CNT; i++) 1659 1721 pThis->afQueueAttached[i] = false; 1660 1722 } … … 1720 1782 static DECLCALLBACK(int) virtioScsiR3DeviceQueryStatusLed(PPDMILEDPORTS pInterface, unsigned iTarget, PPDMLED *ppLed) 1721 1783 { 1722 PVIRTIOSCSI pThis = RT_FROM_MEMBER(pInterface, VIRTIOSCSI, ILeds); 1784 PVIRTIOSCSICC pThisCC = RT_FROM_MEMBER(pInterface, VIRTIOSCSICC, ILeds); 1785 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pThisCC->pDevIns, PVIRTIOSCSI); 1723 1786 if (iTarget < pThis->cTargets) 1724 1787 { 1725 *ppLed = &pThis ->paTargetInstances[iTarget].led;1788 *ppLed = &pThisCC->paTargetInstances[iTarget].led; 1726 1789 Assert((*ppLed)->u32Magic == PDMLED_MAGIC); 1727 1790 return VINF_SUCCESS; … … 1742 1805 { 1743 1806 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaPort); 1744 PPDMDEVINS pDevIns = pTarget->pVirtioScsi->CTX_SUFF(pDevIns);1807 PPDMDEVINS pDevIns = pTarget->pDevIns; 1745 1808 1746 1809 AssertPtrReturn(ppcszController, VERR_INVALID_POINTER); … … 1887 1950 static DECLCALLBACK(void *) virtioScsiR3DeviceQueryInterface(PPDMIBASE pInterface, const char *pszIID) 1888 1951 { 1889 PVIRTIOSCSI pThis = RT_FROM_MEMBER(pInterface, VIRTIOSCSI, IBase);1890 1891 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis ->IBase);1892 PDMIBASE_RETURN_INTERFACE(pszIID, PDMILEDPORTS, &pThis ->ILeds);1952 PVIRTIOSCSICC pThisCC = RT_FROM_MEMBER(pInterface, VIRTIOSCSICC, IBase); 1953 1954 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThisCC->IBase); 1955 PDMIBASE_RETURN_INTERFACE(pszIID, PDMILEDPORTS, &pThisCC->ILeds); 1893 1956 1894 1957 return NULL; … … 1927 1990 static DECLCALLBACK(int) virtioScsiR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass) 1928 1991 { 1929 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 1992 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 1993 PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC); 1930 1994 LogFunc(("LOAD EXEC!!\n")); 1931 1995 … … 1953 2017 SSMR3GetU32(pSSM, &pThis->fHasLunChange); 1954 2018 SSMR3GetU32(pSSM, &pThis->fResetting); 1955 int rc = SSMR3GetU32(pSSM, &pThis ->fQuiescing);2019 int rc = SSMR3GetU32(pSSM, &pThisCC->fQuiescing); 1956 2020 AssertRCReturn(rc, rc); 1957 2021 … … 1967 2031 static DECLCALLBACK(int) virtioScsiR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 1968 2032 { 1969 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2033 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2034 PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC); 1970 2035 LogFunc(("SAVE EXEC!!\n")); 1971 2036 … … 1992 2057 SSMR3PutU32(pSSM, pThis->fHasLunChange); 1993 2058 SSMR3PutU32(pSSM, pThis->fResetting); 1994 SSMR3PutU32(pSSM, pThis ->fQuiescing); /** @todo r=bird: This shall always be false, as the VM is suspended when saving, so no need to save this */2059 SSMR3PutU32(pSSM, pThisCC->fQuiescing); /** @todo r=bird: This shall always be false, as the VM is suspended when saving, so no need to save this */ 1995 2060 1996 2061 /* … … 2013 2078 static DECLCALLBACK(void) virtioScsiR3Detach(PPDMDEVINS pDevIns, unsigned iTarget, uint32_t fFlags) 2014 2079 { 2015 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2016 PVIRTIOSCSITARGET pTarget = &pThis->paTargetInstances[iTarget]; 2080 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2081 PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC); 2082 AssertReturnVoid(iTarget < pThis->cTargets); 2083 PVIRTIOSCSITARGET pTarget = &pThisCC->paTargetInstances[iTarget]; 2017 2084 2018 2085 LogFunc(("")); … … 2023 2090 2024 2091 /* 2025 * Zero someimportant members.2092 * Zero all important members. 2026 2093 */ 2027 pTarget->fPresent = false; 2028 pTarget->pDrvBase = NULL; 2094 pTarget->fPresent = false; 2095 pTarget->pDrvBase = NULL; 2096 pTarget->pDrvMedia = NULL; 2097 pTarget->pDrvMediaEx = NULL; 2098 pTarget->pMediaNotify = NULL; 2029 2099 } 2030 2100 … … 2037 2107 { 2038 2108 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2039 PVIRTIOSCSITARGET pTarget = &pThis->paTargetInstances[iTarget]; 2040 int rc; 2041 2042 pThis->pDevInsR3 = pDevIns; 2043 pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns); 2044 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 2045 2109 PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC); 2110 AssertReturn(iTarget < pThis->cTargets, VERR_PDM_LUN_NOT_FOUND); 2111 PVIRTIOSCSITARGET pTarget = &pThisCC->paTargetInstances[iTarget]; 2112 2113 Assert(pTarget->pDevIns == pDevIns); 2046 2114 AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG, 2047 2115 ("virtio-scsi: Device does not support hotplugging\n"), … … 2056 2124 * required as well as optional. 2057 2125 */ 2058 rc = PDMDevHlpDriverAttach(pDevIns, pTarget->iTarget, &pDevIns->IBase, 2059 &pTarget->pDrvBase, (const char *)&pTarget->pszTargetName); 2126 int rc = PDMDevHlpDriverAttach(pDevIns, pTarget->iTarget, &pDevIns->IBase, &pTarget->pDrvBase, pTarget->pszTargetName); 2060 2127 if (RT_SUCCESS(rc)) 2128 { 2061 2129 pTarget->fPresent = true; 2130 /** @todo r=bird: Shouldn't you resolve pDrvMedia, pDrvMediaEx and 2131 * pMediaNotify here?!? */ 2132 } 2062 2133 else 2063 2134 AssertMsgFailed(("Failed to attach %s. rc=%Rrc\n", pTarget->pszTargetName, rc)); … … 2065 2136 if (RT_FAILURE(rc)) 2066 2137 { 2067 pTarget->fPresent = false; 2068 pTarget->pDrvBase = NULL; 2138 pTarget->fPresent = false; 2139 pTarget->pDrvBase = NULL; 2140 pTarget->pDrvMedia = NULL; 2141 pTarget->pDrvMediaEx = NULL; 2142 pTarget->pMediaNotify = NULL; 2069 2143 } 2070 2144 return rc; … … 2076 2150 static DECLCALLBACK(bool) virtioScsiR3DeviceQuiesced(PPDMDEVINS pDevIns) 2077 2151 { 2078 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2079 LogFunc(("Device I/O activity quiesced: enmQuiescingFor=%d\n", pThis->enmQuiescingFor)); 2080 2081 if (pThis->enmQuiescingFor == kvirtIoScsiQuiescingForReset) 2082 virtioR3PropagateResetNotification(&pThis->Virtio); 2152 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2153 PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC); 2154 LogFunc(("Device I/O activity quiesced: enmQuiescingFor=%d\n", pThisCC->enmQuiescingFor)); 2155 2156 if (pThisCC->enmQuiescingFor == kvirtIoScsiQuiescingForReset) 2157 virtioR3PropagateResetNotification(pDevIns, &pThis->Virtio); 2083 2158 /** @todo r=bird: Do we need other notifications here for suspend and/or poweroff? */ 2084 2159 2085 pThis ->enmQuiescingFor = kvirtIoScsiQuiescingForInvalid;2086 pThis ->fQuiescing = false;2160 pThisCC->enmQuiescingFor = kvirtIoScsiQuiescingForInvalid; 2161 pThisCC->fQuiescing = false; 2087 2162 return true; 2088 2163 } … … 2093 2168 static void virtioScsiR3QuiesceDevice(PPDMDEVINS pDevIns, VIRTIOSCSIQUIESCINGFOR enmQuiscingFor) 2094 2169 { 2095 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2170 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2171 PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC); 2096 2172 2097 2173 /* Prevent worker threads from removing/processing elements from virtq's */ 2098 pThis ->fQuiescing = true;2099 pThis ->enmQuiescingFor = enmQuiscingFor;2174 pThisCC->fQuiescing = true; 2175 pThisCC->enmQuiescingFor = enmQuiscingFor; 2100 2176 2101 2177 PDMDevHlpSetAsyncNotification(pDevIns, virtioScsiR3DeviceQuiesced); … … 2111 2187 static void virtioScsiR3SuspendOrPowerOff(PPDMDEVINS pDevIns, VIRTIOSCSIQUIESCINGFOR enmQuiscingFor) 2112 2188 { 2113 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2189 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2190 PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC); 2114 2191 2115 2192 virtioScsiR3QuiesceDevice(pDevIns, enmQuiscingFor); … … 2124 2201 for (uint32_t i = 0; i < pThis->cTargets; i++) 2125 2202 { 2126 PVIRTIOSCSITARGET pTarget = &pThis->paTargetInstances[i]; 2127 if (pTarget->pDrvBase) 2128 if (pTarget->pDrvMediaEx) 2129 pTarget->pDrvMediaEx->pfnNotifySuspend(pTarget->pDrvMediaEx); 2203 PVIRTIOSCSITARGET pTarget = &pThisCC->paTargetInstances[i]; 2204 if (pTarget->pDrvMediaEx) 2205 pTarget->pDrvMediaEx->pfnNotifySuspend(pTarget->pDrvMediaEx); 2130 2206 } 2131 2207 } … … 2154 2230 static DECLCALLBACK(void) virtioScsiR3Resume(PPDMDEVINS pDevIns) 2155 2231 { 2156 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2232 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2233 PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC); 2157 2234 LogFunc(("\n")); 2158 2235 2159 pThis ->fQuiescing = false;2236 pThisCC->fQuiescing = false; 2160 2237 2161 2238 /* Wake worker threads flagged to skip pulling queue entries during quiesce … … 2165 2242 for (uint16_t qIdx = 0; qIdx < VIRTIOSCSI_REQ_QUEUE_CNT; qIdx++) 2166 2243 { 2167 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[qIdx]; 2168 2169 if (ASMAtomicReadBool(&pWorker->fSleeping)) 2244 if (ASMAtomicReadBool(&pThisCC->aWorkers[qIdx].fSleeping)) 2170 2245 { 2171 2246 Log6Func(("waking %s worker.\n", QUEUENAME(qIdx))); 2172 int rc = SUPSemEventSignal(pThis->pSupDrvSession, pWorker->hEvtProcess);2247 int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->aWorkers[qIdx].hEvtProcess); 2173 2248 AssertRC(rc); 2174 2249 } … … 2176 2251 2177 2252 /* Ensure guest is working the queues too. */ 2178 virtioR3PropagateResumeNotification( &pThis->Virtio);2253 virtioR3PropagateResumeNotification(pDevIns, &pThis->Virtio); 2179 2254 } 2180 2255 … … 2198 2273 { 2199 2274 PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns); 2200 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2201 2202 RTMemFree(pThis->paTargetInstances); 2203 pThis->paTargetInstances = NULL; 2275 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2276 PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC); 2277 2278 RTMemFree(pThisCC->paTargetInstances); 2279 pThisCC->paTargetInstances = NULL; 2204 2280 2205 2281 for (unsigned qIdx = 0; qIdx < VIRTIOSCSI_QUEUE_CNT; qIdx++) … … 2208 2284 if (pWorker->hEvtProcess != NIL_SUPSEMEVENT) 2209 2285 { 2210 SUPSemEventClose(pThis->pSupDrvSession, pWorker->hEvtProcess);2286 PDMDevHlpSUPSemEventClose(pDevIns, pWorker->hEvtProcess); 2211 2287 pWorker->hEvtProcess = NIL_SUPSEMEVENT; 2212 2288 } 2213 2289 } 2214 2290 2215 virtioR3Term( &pThis->Virtio, pDevIns);2291 virtioR3Term(pDevIns, &pThis->Virtio, &pThisCC->Virtio); 2216 2292 return VINF_SUCCESS; 2217 2293 } … … 2223 2299 { 2224 2300 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); 2225 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2226 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 2301 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 2302 PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC); 2303 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 2227 2304 2228 2305 /* 2229 2306 * Quick initialization of the state data, making sure that the destructor always works. 2230 2307 */ 2231 pThis->pDevInsR3 = pDevIns; 2232 pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns); 2233 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 2234 pThis->pSupDrvSession = PDMDevHlpGetSupDrvSession(pDevIns); 2308 pThisCC->pDevIns = pDevIns; 2235 2309 2236 2310 LogFunc(("PDM device instance: %d\n", iInstance)); 2237 2311 RTStrPrintf(pThis->szInstance, sizeof(pThis->szInstance), "VIRTIOSCSI%d", iInstance); 2238 2312 2239 pThis->IBase.pfnQueryInterface = virtioScsiR3DeviceQueryInterface; 2313 pThisCC->IBase.pfnQueryInterface = virtioScsiR3DeviceQueryInterface; 2314 pThisCC->ILeds.pfnQueryStatusLed = virtioScsiR3DeviceQueryStatusLed; 2240 2315 2241 2316 /* … … 2277 2352 2278 2353 /* Initialize the generic Virtio core: */ 2279 pThis ->Virtio.Callbacks.pfnStatusChanged = virtioScsiR3StatusChanged;2280 pThis ->Virtio.Callbacks.pfnQueueNotified = virtioScsiR3Notified;2281 pThis ->Virtio.Callbacks.pfnDevCapRead = virtioScsiR3DevCapRead;2282 pThis ->Virtio.Callbacks.pfnDevCapWrite = virtioScsiR3DevCapWrite;2354 pThisCC->Virtio.Callbacks.pfnStatusChanged = virtioScsiR3StatusChanged; 2355 pThisCC->Virtio.Callbacks.pfnQueueNotified = virtioScsiR3Notified; 2356 pThisCC->Virtio.Callbacks.pfnDevCapRead = virtioScsiR3DevCapRead; 2357 pThisCC->Virtio.Callbacks.pfnDevCapWrite = virtioScsiR3DevCapWrite; 2283 2358 2284 2359 VIRTIOPCIPARAMS VirtioPciParams; … … 2293 2368 VirtioPciParams.uInterruptPin = 0x01; 2294 2369 2295 rc = virtioR3Init(&pThis->Virtio, pDevIns, &VirtioPciParams, pThis->szInstance, VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED, 2370 rc = virtioR3Init(pDevIns, &pThis->Virtio, &pThisCC->Virtio, &VirtioPciParams, pThis->szInstance, 2371 VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED, 2296 2372 &pThis->virtioScsiConfig /*pvDevSpecificCap*/, sizeof(pThis->virtioScsiConfig)); 2297 2373 … … 2318 2394 if (qIdx == CONTROLQ_IDX || IS_REQ_QUEUE(qIdx)) 2319 2395 { 2320 rc = PDMDevHlpThreadCreate(pDevIns, &pThis ->aWorkers[qIdx].pThread,2396 rc = PDMDevHlpThreadCreate(pDevIns, &pThisCC->aWorkers[qIdx].pThread, 2321 2397 (void *)(uintptr_t)qIdx, virtioScsiR3WorkerThread, 2322 2398 virtioScsiR3WorkerWakeUp, 0, RTTHREADTYPE_IO, QUEUENAME(qIdx)); … … 2327 2403 } 2328 2404 2329 rc = SUPSemEventCreate(pThis->pSupDrvSession, &pThis->aWorkers[qIdx].hEvtProcess);2405 rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pThis->aWorkers[qIdx].hEvtProcess); 2330 2406 if (RT_FAILURE(rc)) 2331 2407 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, … … 2340 2416 Log2Func(("Probing %d targets ...\n", pThis->cTargets)); 2341 2417 2342 pThis ->paTargetInstances = (PVIRTIOSCSITARGET)RTMemAllocZ(sizeof(VIRTIOSCSITARGET) * pThis->cTargets);2343 if (!pThis ->paTargetInstances)2418 pThisCC->paTargetInstances = (PVIRTIOSCSITARGET)RTMemAllocZ(sizeof(VIRTIOSCSITARGET) * pThis->cTargets); 2419 if (!pThisCC->paTargetInstances) 2344 2420 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to allocate memory for target states")); 2345 2421 2346 for ( RTUINTiTarget = 0; iTarget < pThis->cTargets; iTarget++)2347 { 2348 PVIRTIOSCSITARGET pTarget = &pThis ->paTargetInstances[iTarget];2422 for (uint32_t iTarget = 0; iTarget < pThis->cTargets; iTarget++) 2423 { 2424 PVIRTIOSCSITARGET pTarget = &pThisCC->paTargetInstances[iTarget]; 2349 2425 2350 2426 if (RTStrAPrintf(&pTarget->pszTargetName, "VSCSI%u", iTarget) < 0) … … 2352 2428 2353 2429 /* Initialize static parts of the device. */ 2430 pTarget->pDevIns = pDevIns; 2354 2431 pTarget->iTarget = iTarget; 2355 pTarget->pVirtioScsi = pThis;2356 2432 pTarget->led.u32Magic = PDMLED_MAGIC; 2357 2433 … … 2372 2448 pTarget->IBase.pfnQueryInterface = virtioScsiR3TargetQueryInterface; 2373 2449 pTarget->ILed.pfnQueryStatusLed = virtioScsiR3TargetQueryStatusLed; 2374 pThis->ILeds.pfnQueryStatusLed = virtioScsiR3DeviceQueryStatusLed;2375 2450 pTarget->led.u32Magic = PDMLED_MAGIC; 2376 2451 … … 2400 2475 2401 2476 pTarget->pMediaNotify = PDMIBASE_QUERY_INTERFACE(pTarget->pDrvBase, PDMIMEDIANOTIFY); 2402 AssertMsgReturn(VALID_PTR(pTarget->p DrvMediaEx),2477 AssertMsgReturn(VALID_PTR(pTarget->pMediaNotify), 2403 2478 ("virtio-scsi configuration error: LUN#%u: Failed to get set Media notify obj!\n", iTarget), 2404 2479 VERR_PDM_MISSING_INTERFACE); … … 2424 2499 PPDMIBASE pUpBase; 2425 2500 AssertCompile(PDM_STATUS_LUN >= VIRTIOSCSI_MAX_TARGETS); 2426 rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pThis ->IBase, &pUpBase, "Status Port");2501 rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pThisCC->IBase, &pUpBase, "Status Port"); 2427 2502 if (RT_FAILURE(rc) && rc != VERR_PDM_NO_ATTACHED_DRIVER) 2428 2503 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to attach the status LUN")); -
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp
r81662 r81675 121 121 * Internal Functions * 122 122 *********************************************************************************************************************************/ 123 static void virtioNotifyGuestDriver(P VIRTIOSTATE pVirtio, uint16_t idxQueue, bool fForce);124 static int virtioKick(P VIRTIOSTATE pVirtio, uint8_t uCause, uint16_t uVec, bool fForce);123 static void virtioNotifyGuestDriver(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, bool fForce); 124 static int virtioKick(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint8_t uCause, uint16_t uVec, bool fForce); 125 125 126 126 /** @name Internal queue operations … … 137 137 * Accessor for virtq descriptor 138 138 */ 139 DECLINLINE(void) virtioReadDesc(PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint32_t uDescIdx, PVIRTQ_DESC_T pDesc) 139 DECLINLINE(void) virtioReadDesc(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, 140 uint32_t idxDesc, PVIRTQ_DESC_T pDesc) 140 141 { 141 142 //Log(("%s virtioQueueReadDesc: ring=%p idx=%u\n", INSTANCE(pState), pVirtQ, idx)); 142 143 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 143 PDMDevHlpPhysRead(pVirtio->CTX_SUFF(pDevIns), 144 pVirtio->aGCPhysQueueDesc[idxQueue] + sizeof(VIRTQ_DESC_T) * (uDescIdx % pVirtio->uQueueSize[idxQueue]), 144 uint16_t const cQueueItems = RT_MAX(pVirtio->uQueueSize[idxQueue], 1); /* Make sure to avoid div-by-zero. */ 145 PDMDevHlpPhysRead(pDevIns, /** @todo r=bird: PDMDevHlpPhysRead or PDMDevHlpPCIPhysRead ?!? (ditto rest of file + writes) */ 146 pVirtio->aGCPhysQueueDesc[idxQueue] + sizeof(VIRTQ_DESC_T) * (idxDesc % cQueueItems), 145 147 pDesc, sizeof(VIRTQ_DESC_T)); 146 148 } … … 149 151 * Accessors for virtq avail ring 150 152 */ 151 DECLINLINE(uint16_t) virtioReadAvailDescIdx(P VIRTIOSTATE pVirtio, uint16_t idxQueue, uint32_t availIdx)153 DECLINLINE(uint16_t) virtioReadAvailDescIdx(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint32_t availIdx) 152 154 { 153 155 uint16_t uDescIdx; 154 156 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 155 PDMDevHlpPhysRead(pVirtio->CTX_SUFF(pDevIns), 157 uint16_t const cQueueItems = RT_MAX(pVirtio->uQueueSize[idxQueue], 1); /* Make sure to avoid div-by-zero. */ 158 PDMDevHlpPhysRead(pDevIns, 156 159 pVirtio->aGCPhysQueueAvail[idxQueue] 157 + RT_UOFFSETOF_DYN(VIRTQ_AVAIL_T, auRing[availIdx % pVirtio->uQueueSize[idxQueue]]),160 + RT_UOFFSETOF_DYN(VIRTQ_AVAIL_T, auRing[availIdx % cQueueItems]), 158 161 &uDescIdx, sizeof(uDescIdx)); 159 162 return uDescIdx; 160 163 } 161 164 162 DECLINLINE(uint16_t) virtioReadAvailRingIdx(P VIRTIOSTATE pVirtio, uint16_t idxQueue)165 DECLINLINE(uint16_t) virtioReadAvailRingIdx(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue) 163 166 { 164 167 uint16_t uIdx = 0; 165 168 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 166 PDMDevHlpPhysRead(p Virtio->CTX_SUFF(pDevIns),169 PDMDevHlpPhysRead(pDevIns, 167 170 pVirtio->aGCPhysQueueAvail[idxQueue] + RT_UOFFSETOF(VIRTQ_AVAIL_T, uIdx), 168 171 &uIdx, sizeof(uIdx)); … … 170 173 } 171 174 172 DECLINLINE(bool) virtqIsEmpty(P VIRTIOSTATE pVirtio, uint16_t idxQueue)173 { 174 return virtioReadAvailRingIdx(p Virtio, idxQueue) == pVirtio->virtqState[idxQueue].uAvailIdx;175 DECLINLINE(bool) virtqIsEmpty(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue) 176 { 177 return virtioReadAvailRingIdx(pDevIns, pVirtio, idxQueue) == pVirtio->virtqState[idxQueue].uAvailIdx; 175 178 } 176 179 177 180 #if 0 /* unused */ 178 DECLINLINE(uint16_t) virtioReadAvailFlags(P VIRTIOSTATE pVirtio, uint16_t idxQueue)181 DECLINLINE(uint16_t) virtioReadAvailFlags(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue) 179 182 { 180 183 uint16_t fFlags; 181 184 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 182 PDMDevHlpPhysRead(p Virtio->CTX_SUFF(pDevIns),185 PDMDevHlpPhysRead(pDevIns, 183 186 pVirtio->aGCPhysQueueAvail[idxQueue] + RT_UOFFSETOF(VIRTQ_AVAIL_T, fFlags), 184 187 &fFlags, sizeof(fFlags)); … … 187 190 #endif 188 191 189 DECLINLINE(uint16_t) virtioReadAvailUsedEvent(P VIRTIOSTATE pVirtio, uint16_t idxQueue)192 DECLINLINE(uint16_t) virtioReadAvailUsedEvent(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue) 190 193 { 191 194 uint16_t uUsedEventIdx; 192 /* *VirtIO 1.0 uUsedEventIdx (used_event) immediately follows ring */195 /* VirtIO 1.0 uUsedEventIdx (used_event) immediately follows ring */ 193 196 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 194 PDMDevHlpPhysRead(p Virtio->CTX_SUFF(pDevIns),197 PDMDevHlpPhysRead(pDevIns, 195 198 pVirtio->aGCPhysQueueAvail[idxQueue] + RT_UOFFSETOF_DYN(VIRTQ_AVAIL_T, auRing[pVirtio->uQueueSize[idxQueue]]), 196 199 &uUsedEventIdx, sizeof(uUsedEventIdx)); … … 202 205 * @{ 203 206 */ 204 DECLINLINE(void) virtioWriteUsedElem(PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint32_t usedIdx, uint32_t uDescIdx, uint32_t uLen) 207 DECLINLINE(void) virtioWriteUsedElem(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, 208 uint32_t usedIdx, uint32_t uDescIdx, uint32_t uLen) 205 209 { 206 210 VIRTQ_USED_ELEM_T elem = { uDescIdx, uLen }; 207 211 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 208 PDMDevHlpPCIPhysWrite(pVirtio->CTX_SUFF(pDevIns),209 pVirtio->aGCPhysQueueUsed[idxQueue]210 + RT_UOFFSETOF_DYN(VIRTQ_USED_T, aRing[usedIdx % pVirtio->uQueueSize[idxQueue]]),212 uint16_t const cQueueItems = RT_MAX(pVirtio->uQueueSize[idxQueue], 1); /* Make sure to avoid div-by-zero. */ 213 PDMDevHlpPCIPhysWrite(pDevIns, 214 pVirtio->aGCPhysQueueUsed[idxQueue] + RT_UOFFSETOF_DYN(VIRTQ_USED_T, aRing[usedIdx % cQueueItems]), 211 215 &elem, sizeof(elem)); 212 216 } 213 217 214 DECLINLINE(void) virtioWriteUsedRingIdx(P VIRTIOSTATE pVirtio, uint16_t idxQueue, uint16_t uIdx)218 DECLINLINE(void) virtioWriteUsedRingIdx(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint16_t uIdx) 215 219 { 216 220 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 217 PDMDevHlpPCIPhysWrite(p Virtio->CTX_SUFF(pDevIns),221 PDMDevHlpPCIPhysWrite(pDevIns, 218 222 pVirtio->aGCPhysQueueUsed[idxQueue] + RT_UOFFSETOF(VIRTQ_USED_T, uIdx), 219 223 &uIdx, sizeof(uIdx)); … … 221 225 222 226 #ifdef LOG_ENABLED 223 DECLINLINE(uint16_t) virtioReadUsedRingIdx(P VIRTIOSTATE pVirtio, uint16_t idxQueue)224 { 225 uint16_t uIdx ;227 DECLINLINE(uint16_t) virtioReadUsedRingIdx(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue) 228 { 229 uint16_t uIdx = 0; 226 230 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 227 PDMDevHlpPhysRead(p Virtio->CTX_SUFF(pDevIns),231 PDMDevHlpPhysRead(pDevIns, 228 232 pVirtio->aGCPhysQueueUsed[idxQueue] + RT_UOFFSETOF(VIRTQ_USED_T, uIdx), 229 233 &uIdx, sizeof(uIdx)); … … 232 236 #endif 233 237 234 DECLINLINE(uint16_t) virtioReadUsedFlags(P VIRTIOSTATE pVirtio, uint16_t idxQueue)235 { 236 uint16_t fFlags ;238 DECLINLINE(uint16_t) virtioReadUsedFlags(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue) 239 { 240 uint16_t fFlags = 0; 237 241 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 238 PDMDevHlpPhysRead(p Virtio->CTX_SUFF(pDevIns),242 PDMDevHlpPhysRead(pDevIns, 239 243 pVirtio->aGCPhysQueueUsed[idxQueue] + RT_UOFFSETOF(VIRTQ_USED_T, fFlags), 240 244 &fFlags, sizeof(fFlags)); … … 243 247 244 248 #if 0 /* unused */ 245 DECLINLINE(void) virtioWriteUsedFlags(P VIRTIOSTATE pVirtio, uint16_t idxQueue, uint32_t fFlags)249 DECLINLINE(void) virtioWriteUsedFlags(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint32_t fFlags) 246 250 { 247 251 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 248 252 RT_UNTRUSTED_VALIDATED_FENCE(); /* VirtIO 1.0, Section 3.2.1.4.1 */ 249 PDMDevHlpPCIPhysWrite(p Virtio->CTX_SUFF(pDevIns),253 PDMDevHlpPCIPhysWrite(pDevIns, 250 254 pVirtio->aGCPhysQueueUsed[idxQueue] + RT_UOFFSETOF(VIRTQ_USED_T, fFlags), 251 255 &fFlags, sizeof(fFlags)); … … 254 258 255 259 #if 0 /* unused */ 256 DECLINLINE(uint16_t) virtioReadUsedAvailEvent(P VIRTIOSTATE pVirtio, uint16_t idxQueue)260 DECLINLINE(uint16_t) virtioReadUsedAvailEvent(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue) 257 261 { 258 262 uint16_t uAvailEventIdx; … … 260 264 /** VirtIO 1.0 uAvailEventIdx (avail_event) immediately follows ring */ 261 265 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 262 PDMDevHlpPhysRead(p Virtio->CTX_SUFF(pDevIns),266 PDMDevHlpPhysRead(pDevIns, 263 267 pVirtio->aGCPhysQueueUsed[idxQueue] + RT_UOFFSETOF_DYN(VIRTQ_USED_T, aRing[pVirtio->uQueueSize[idxQueue]]), 264 268 &uAvailEventIdx, sizeof(uAvailEventIdx)); … … 268 272 269 273 #if 0 /* unused */ 270 DECLINLINE(void) virtioWriteUsedAvailEvent(P VIRTIOSTATE pVirtio, uint16_t idxQueue, uint32_t uAvailEventIdx)274 DECLINLINE(void) virtioWriteUsedAvailEvent(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint32_t uAvailEventIdx) 271 275 { 272 276 /** VirtIO 1.0 uAvailEventIdx (avail_event) immediately follows ring */ 273 277 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 274 PDMDevHlpPCIPhysWrite(p Virtio->CTX_SUFF(pDevIns),278 PDMDevHlpPCIPhysWrite(pDevIns, 275 279 pVirtio->aGCPhysQueueUsed[idxQueue] + RT_UOFFSETOF_DYN(VIRTQ_USED_T, aRing[pVirtio->uQueueSize[idxQueue]]), 276 280 &uAvailEventIdx, sizeof(uAvailEventIdx)); … … 411 415 * Allocate client context for client to work with VirtIO-provided with queue 412 416 * 413 * @param pVirtio Pointer to the virtio state.417 * @param pVirtio Pointer to the shared virtio state. 414 418 * @param idxQueue Queue number 415 419 * @param pcszName Name to give queue … … 454 458 * Check if the associated queue is empty 455 459 * 456 * @param hVirtio Handle for VirtIO framework 457 * @param idxQueue Queue number 460 * @param pDevIns The device instance (for reading). 461 * @param pVirtio Pointer to the shared virtio state. 462 * @param idxQueue Queue number 458 463 * 459 464 * @retval true Queue is empty or unavailable. 460 465 * @retval false Queue is available and has entries 461 466 */ 462 bool virtioQueueIsEmpty(P VIRTIOSTATE pVirtio, uint16_t idxQueue)467 bool virtioQueueIsEmpty(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue) 463 468 { 464 469 if (pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK) 465 return virtqIsEmpty(p Virtio, idxQueue);470 return virtqIsEmpty(pDevIns, pVirtio, idxQueue); 466 471 return true; 467 472 } … … 478 483 * at some point to return the data to the guest and complete the transaction. 479 484 * 480 * @param pVirtio Pointer to the virtio state. 485 * @param pDevIns The device instance. 486 * @param pVirtio Pointer to the shared virtio state. 481 487 * @param idxQueue Queue number 482 488 * @param fRemove flags whether to remove desc chain from queue (false = peek) … … 489 495 * @retval VERR_NOT_AVAILABLE If the queue is empty. 490 496 */ 491 int virtioR3QueueGet(PVIRTIOSTATE pVirtio, uint16_t idxQueue, PPVIRTIO_DESC_CHAIN_T ppDescChain, bool fRemove) 497 int virtioR3QueueGet(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, 498 PPVIRTIO_DESC_CHAIN_T ppDescChain, bool fRemove) 492 499 { 493 500 AssertReturn(ppDescChain, VERR_INVALID_PARAMETER); … … 505 512 ("Guest driver not in ready state.\n"), VERR_INVALID_STATE); 506 513 507 if (virtqIsEmpty(p Virtio, idxQueue))514 if (virtqIsEmpty(pDevIns, pVirtio, idxQueue)) 508 515 return VERR_NOT_AVAILABLE; 509 516 510 uint16_t uHeadIdx = virtioReadAvailDescIdx(p Virtio, idxQueue, pVirtq->uAvailIdx);517 uint16_t uHeadIdx = virtioReadAvailDescIdx(pDevIns, pVirtio, idxQueue, pVirtq->uAvailIdx); 511 518 uint16_t uDescIdx = uHeadIdx; 512 519 … … 545 552 RT_UNTRUSTED_VALIDATED_FENCE(); 546 553 547 virtioReadDesc(p Virtio, idxQueue, uDescIdx, &desc);554 virtioReadDesc(pDevIns, pVirtio, idxQueue, uDescIdx, &desc); 548 555 549 556 if (desc.fFlags & VIRTQ_DESC_F_WRITE) … … 604 611 * 605 612 * 606 * @param pVirtio Pointer to the virtio state. 613 * @param pDevIns The device instance (for reading). 614 * @param pVirtio Pointer to the shared virtio state. 607 615 * @param idxQueue Queue number 608 616 * … … 621 629 * @retval VERR_NOT_AVAILABLE Queue is empty 622 630 */ 623 int virtioR3QueuePut(P VIRTIOSTATE pVirtio, uint16_t idxQueue, PRTSGBUF pSgVirtReturn,631 int virtioR3QueuePut(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, PRTSGBUF pSgVirtReturn, 624 632 PVIRTIO_DESC_CHAIN_T pDescChain, bool fFence) 625 633 { … … 632 640 633 641 Log3Func(("Copying client data to %s, desc chain (head desc_idx %d)\n", 634 QUEUENAME(pVirtio, idxQueue), virtioReadUsedRingIdx(p Virtio, idxQueue)));642 QUEUENAME(pVirtio, idxQueue), virtioReadUsedRingIdx(pDevIns, pVirtio, idxQueue))); 635 643 636 644 /* … … 650 658 uint64_t dstSgCur = (uint64_t)pSgPhysReturn->pvSegCur; 651 659 cbCopy = RT_MIN((uint64_t)pSgVirtReturn->cbSegLeft, dstSgLen - (dstSgCur - dstSgStart)); 652 PDMDevHlpPhysWrite(pVirtio->CTX_SUFF(pDevIns), 653 (RTGCPHYS)pSgPhysReturn->pvSegCur, pSgVirtReturn->pvSegCur, cbCopy); 660 PDMDevHlpPhysWrite(pDevIns, (RTGCPHYS)pSgPhysReturn->pvSegCur, pSgVirtReturn->pvSegCur, cbCopy); 654 661 RTSgBufAdvance(pSgVirtReturn, cbCopy); 655 662 RTSgBufAdvance(pSgPhysReturn, cbCopy); … … 660 667 RT_UNTRUSTED_NONVOLATILE_COPY_FENCE(); /* needed? */ 661 668 662 /* *If this write-ahead crosses threshold where the driver wants to get an event flag it */669 /* If this write-ahead crosses threshold where the driver wants to get an event flag it */ 663 670 if (pVirtio->uDriverFeatures & VIRTIO_F_EVENT_IDX) 664 if (pVirtq->uUsedIdx == virtioReadAvailUsedEvent(p Virtio, idxQueue))671 if (pVirtq->uUsedIdx == virtioReadAvailUsedEvent(pDevIns, pVirtio, idxQueue)) 665 672 pVirtq->fEventThresholdReached = true; 666 673 667 Assert(!(cbCopy & UINT64_C(0xffffffff00000000)));674 Assert(!(cbCopy >> 32)); 668 675 669 676 /* 670 677 * Place used buffer's descriptor in used ring but don't update used ring's slot index. 671 678 * That will be done with a subsequent client call to virtioQueueSync() */ 672 virtioWriteUsedElem(p Virtio, idxQueue, pVirtq->uUsedIdx++, pDescChain->uHeadIdx, (uint32_t)(cbCopy & UINT32_C(0xffffffff)));673 674 Log2Func((".... Copied % lu bytes to %lu byte buffer, residual=%lu\n",679 virtioWriteUsedElem(pDevIns, pVirtio, idxQueue, pVirtq->uUsedIdx++, pDescChain->uHeadIdx, (uint32_t)cbCopy); 680 681 Log2Func((".... Copied %zu bytes to %u byte buffer, residual=%zu\n", 675 682 cbCopy, pDescChain->cbPhysReturn, pDescChain->cbPhysReturn - cbCopy)); 676 683 677 Log6Func(("Write ahead used_idx=% d, %s used_idx=%d\n",678 pVirtq->uUsedIdx, QUEUENAME(pVirtio, idxQueue), virtioReadUsedRingIdx(p Virtio, idxQueue)));684 Log6Func(("Write ahead used_idx=%u, %s used_idx=%u\n", 685 pVirtq->uUsedIdx, QUEUENAME(pVirtio, idxQueue), virtioReadUsedRingIdx(pDevIns, pVirtio, idxQueue))); 679 686 680 687 RTMemFree((void *)pDescChain->pSgPhysSend->paSegs); … … 699 706 * specification, Section 2.4 "Virtqueues"). 700 707 * 701 * @param pVirtio Pointer to the virtio state. 708 * @param pDevIns The device instance. 709 * @param pVirtio Pointer to the shared virtio state. 702 710 * @param idxQueue Queue number 703 711 * … … 706 714 * @retval VERR_INVALID_STATE VirtIO not in ready state 707 715 */ 708 int virtioQueueSync(P VIRTIOSTATE pVirtio, uint16_t idxQueue)716 int virtioQueueSync(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue) 709 717 { 710 718 Assert(idxQueue < RT_ELEMENTS(pVirtio->virtqState)); … … 715 723 716 724 Log6Func(("Updating %s used_idx from %u to %u\n", 717 QUEUENAME(pVirtio, idxQueue), virtioReadUsedRingIdx(p Virtio, idxQueue), pVirtq->uUsedIdx));718 719 virtioWriteUsedRingIdx(p Virtio, idxQueue, pVirtq->uUsedIdx);720 virtioNotifyGuestDriver(p Virtio, idxQueue, false);725 QUEUENAME(pVirtio, idxQueue), virtioReadUsedRingIdx(pDevIns, pVirtio, idxQueue), pVirtq->uUsedIdx)); 726 727 virtioWriteUsedRingIdx(pDevIns, pVirtio, idxQueue, pVirtq->uUsedIdx); 728 virtioNotifyGuestDriver(pDevIns, pVirtio, idxQueue, false); 721 729 722 730 return VINF_SUCCESS; … … 726 734 /** 727 735 */ 728 static void virtio r3QueueNotified(PVIRTIOSTATE pVirtio, uint16_t idxQueue, uint16_t uNotifyIdx)736 static void virtioR3QueueNotified(PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC, uint16_t idxQueue, uint16_t uNotifyIdx) 729 737 { 730 738 /* See VirtIO 1.0, section 4.1.5.2 It implies that idxQueue and uNotifyIdx should match. … … 742 750 743 751 AssertReturnVoid(idxQueue < RT_ELEMENTS(pVirtio->virtqState)); 744 PVIRTQSTATE pVirtq = &pVirtio->virtqState[idxQueue]; 745 Log6Func(("%s\n", pVirtq->szVirtqName)); 746 RT_NOREF(pVirtq); 752 Log6Func(("%s\n", pVirtio->virtqState[idxQueue].szVirtqName)); 747 753 748 754 /* Inform client */ 749 pVirtio ->Callbacks.pfnQueueNotified(pVirtio, idxQueue);755 pVirtioCC->Callbacks.pfnQueueNotified(pVirtio, pVirtioCC, idxQueue); 750 756 } 751 757 #endif /* IN_RING3 */ … … 758 764 * See VirtIO 1.0 specification (section 2.4.7). 759 765 * 760 * @param pVirtio Pointer to the virtio state. 766 * @param pDevIns The device instance. 767 * @param pVirtio Pointer to the shared virtio state. 761 768 * @param idxQueue Queue to check for guest interrupt handling preference 762 769 * @param fForce Overrides idxQueue, forcing notification regardless of driver's … … 766 773 * as they only cause the guest driver to [re]scan queues for work to do. 767 774 */ 768 static void virtioNotifyGuestDriver(P VIRTIOSTATE pVirtio, uint16_t idxQueue, bool fForce)775 static void virtioNotifyGuestDriver(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, bool fForce) 769 776 { 770 777 Assert(idxQueue < RT_ELEMENTS(pVirtio->virtqState)); … … 776 783 if (pVirtq->fEventThresholdReached) 777 784 { 778 virtioKick(p Virtio, VIRTIO_ISR_VIRTQ_INTERRUPT, pVirtio->uQueueMsixVector[idxQueue], fForce);785 virtioKick(pDevIns, pVirtio, VIRTIO_ISR_VIRTQ_INTERRUPT, pVirtio->uQueueMsixVector[idxQueue], fForce); 779 786 pVirtq->fEventThresholdReached = false; 780 787 return; … … 785 792 { 786 793 /** If guest driver hasn't suppressed interrupts, interrupt */ 787 if (fForce || !(virtioReadUsedFlags(p Virtio, idxQueue) & VIRTQ_AVAIL_F_NO_INTERRUPT))794 if (fForce || !(virtioReadUsedFlags(pDevIns, pVirtio, idxQueue) & VIRTQ_AVAIL_F_NO_INTERRUPT)) 788 795 { 789 virtioKick(p Virtio, VIRTIO_ISR_VIRTQ_INTERRUPT, pVirtio->uQueueMsixVector[idxQueue], fForce);796 virtioKick(pDevIns, pVirtio, VIRTIO_ISR_VIRTQ_INTERRUPT, pVirtio->uQueueMsixVector[idxQueue], fForce); 790 797 return; 791 798 } … … 797 804 * Raise interrupt or MSI-X 798 805 * 799 * @param pVirtio The device state structure. 800 * @param uCause Interrupt cause bit mask to set in PCI ISR port. 801 * @param uVec MSI-X vector, if enabled 802 * @param uForce True of out-of-band 803 */ 804 static int virtioKick(PVIRTIOSTATE pVirtio, uint8_t uCause, uint16_t uMsixVector, bool fForce) 806 * @param pDevIns The device instance. 807 * @param pVirtio Pointer to the shared virtio state. 808 * @param uCause Interrupt cause bit mask to set in PCI ISR port. 809 * @param uVec MSI-X vector, if enabled 810 * @param uForce True of out-of-band 811 */ 812 static int virtioKick(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint8_t uCause, uint16_t uMsixVector, bool fForce) 805 813 { 806 814 if (fForce) … … 816 824 { 817 825 pVirtio->uISR |= uCause; 818 PDMDevHlpPCISetIrq(p Virtio->CTX_SUFF(pDevIns), 0, PDM_IRQ_LEVEL_HIGH);826 PDMDevHlpPCISetIrq(pDevIns, 0, PDM_IRQ_LEVEL_HIGH); 819 827 } 820 828 else if (uMsixVector != VIRTIO_MSI_NO_VECTOR) 821 829 { 822 830 Log6Func(("MSI-X enabled, calling PDMDevHlpPCISetIrq with vector: 0x%x\n", uMsixVector)); 823 PDMDevHlpPCISetIrq(p Virtio->CTX_SUFF(pDevIns), uMsixVector, 1);831 PDMDevHlpPCISetIrq(pDevIns, uMsixVector, 1); 824 832 } 825 833 return VINF_SUCCESS; … … 829 837 * Lower interrupt. (Called when guest reads ISR) 830 838 * 831 * @param p Virtio The device state structure.832 */ 833 static void virtioLowerInterrupt(P VIRTIOSTATE pVirtio)834 { 835 PDMDevHlpPCISetIrq(p Virtio->CTX_SUFF(pDevIns), 0, PDM_IRQ_LEVEL_LOW);839 * @param pDevIns The device instance. 840 */ 841 static void virtioLowerInterrupt(PPDMDEVINS pDevIns) 842 { 843 PDMDevHlpPCISetIrq(pDevIns, 0, PDM_IRQ_LEVEL_LOW); 836 844 } 837 845 … … 851 859 } 852 860 853 static void virtioResetDevice(P VIRTIOSTATE pVirtio)861 static void virtioResetDevice(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio) 854 862 { 855 863 Log2Func(("\n")); … … 860 868 pVirtio->uISR = 0; 861 869 862 virtioLowerInterrupt(p Virtio);870 virtioLowerInterrupt(pDevIns); 863 871 864 872 if (!pVirtio->fMsiSupport) /* VirtIO 1.0, 4.1.4.3 and 4.1.5.1.2 */ … … 874 882 * Enable or disable queue 875 883 * 876 * @param pVirtio Pointer to the virtio state.884 * @param pVirtio Pointer to the shared virtio state. 877 885 * @param idxQueue Queue number 878 886 * @param fEnabled Flag indicating whether to enable queue or not … … 909 917 * The driver itself will not until the device has read the status change. 910 918 */ 911 static void virtioGuestR3 Resetted(PVIRTIOSTATE pVirtio)919 static void virtioGuestR3WasReset(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC) 912 920 { 913 921 LogFunc(("Guest reset the device\n")); 914 922 915 923 /* Let the client know */ 916 pVirtio ->Callbacks.pfnStatusChanged(pVirtio, 0);917 virtioResetDevice(p Virtio);924 pVirtioCC->Callbacks.pfnStatusChanged(pVirtio, pVirtioCC, 0); 925 virtioResetDevice(pDevIns, pVirtio); 918 926 } 919 927 #endif /* IN_RING3 */ … … 924 932 * @returns VBox status code 925 933 * 926 * @param pVirtio Virtio instance state 934 * @param pDevIns The device instance. 935 * @param pVirtio Pointer to the shared virtio state. 936 * @param pVirtioCC Pointer to the current context virtio state. 927 937 * @param fWrite Set if write access, clear if read access. 928 938 * @param offCfg The common configuration capability offset. … … 930 940 * @param pv Pointer to location to write to or read from 931 941 */ 932 static int virtioCommonCfgAccessed(P VIRTIOSTATE pVirtio, int fWrite, off_t offCfg, unsigned cb, void *pv)942 static int virtioCommonCfgAccessed(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC, int fWrite, off_t offCfg, unsigned cb, void *pv) 933 943 { 934 944 /** … … 1100 1110 if (fWrite) /* Guest WRITE pCommonCfg->uDeviceStatus */ 1101 1111 { 1102 pVirtio->uDeviceStatus = *(uint8_t *)pv; 1103 Log6Func(("Guest wrote uDeviceStatus ................ (")); 1104 virtioLogDeviceStatus(pVirtio->uDeviceStatus); 1112 uint8_t const fNewStatus = *(uint8_t *)pv; 1113 Log6Func(("Guest wrote uDeviceStatus (%#x, was %#x, change #%x) ................ (", 1114 fNewStatus, pVirtio->uDeviceStatus, fNewStatus ^ pVirtio->uDeviceStatus)); 1115 virtioLogDeviceStatus(fNewStatus); 1105 1116 Log6((")\n")); 1117 1118 /* If the status changed or we were reset, we need to go to ring-3 as 1119 it requires notifying the parent device. */ 1120 bool const fStatusChanged = (fNewStatus & VIRTIO_STATUS_DRIVER_OK) 1121 != (pVirtio->uPrevDeviceStatus & VIRTIO_STATUS_DRIVER_OK); 1122 #ifndef IN_RING3 1123 if (fStatusChanged || fNewStatus == 0) 1124 { 1125 Log6Func(("=>ring3\n")); 1126 return VINF_IOM_R3_MMIO_WRITE; 1127 } 1128 #endif 1129 pVirtio->uDeviceStatus = fNewStatus; 1130 1131 #ifdef IN_RING3 1132 /* 1133 * Notify client only if status actually changed from last time and when we're reset. 1134 */ 1106 1135 if (pVirtio->uDeviceStatus == 0) 1107 virtioGuestR3Resetted(pVirtio); 1136 virtioGuestR3WasReset(pDevIns, pVirtio, pVirtioCC); 1137 if (fStatusChanged) 1138 pVirtioCC->Callbacks.pfnStatusChanged(pVirtio, pVirtioCC, fNewStatus & VIRTIO_STATUS_DRIVER_OK); 1139 #endif 1108 1140 /* 1109 * Notify client only if status actually changed from last time.1141 * Save the current status for the next write so we can see what changed. 1110 1142 */ 1111 uint32_t const fOkayNow = pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK;1112 uint32_t const fWasOkay = pVirtio->uPrevDeviceStatus & VIRTIO_STATUS_DRIVER_OK;1113 if (fOkayNow != fWasOkay)1114 pVirtio->Callbacks.pfnStatusChanged(pVirtio, fOkayNow);1115 1143 pVirtio->uPrevDeviceStatus = pVirtio->uDeviceStatus; 1116 1144 } … … 1182 1210 static DECLCALLBACK(VBOXSTRICTRC) virtioMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb) 1183 1211 { 1184 PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE); 1212 PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE); 1213 PVIRTIOSTATECC pVirtioCC = PDMINS_2_DATA_CC(pDevIns, PVIRTIOSTATECC); 1185 1214 Assert(pVirtio == (PVIRTIOSTATE)pvUser); RT_NOREF(pvUser); 1186 1215 … … 1200 1229 * Callback to client to manage device-specific configuration. 1201 1230 */ 1202 VBOXSTRICTRC rcStrict = pVirtio ->Callbacks.pfnDevCapRead(pDevIns, offIntra, pv, cb);1231 VBOXSTRICTRC rcStrict = pVirtioCC->Callbacks.pfnDevCapRead(pDevIns, offIntra, pv, cb); 1203 1232 1204 1233 /* … … 1207 1236 * order to maintain the config generation (see VirtIO 1.0 spec, section 4.1.4.3.1) 1208 1237 */ 1209 bool fDevSpecificFieldChanged = !!memcmp( (char *)pVirtio->pvDevSpecificCfg + offIntra,1210 (char *)pVirtio->pvPrevDevSpecificCfg + offIntra,1211 RT_MIN(cb, pVirtio ->cbDevSpecificCfg - offIntra));1212 1213 memcpy(pVirtio ->pvPrevDevSpecificCfg, pVirtio->pvDevSpecificCfg, pVirtio->cbDevSpecificCfg);1238 bool fDevSpecificFieldChanged = !!memcmp(pVirtioCC->pbDevSpecificCfg + offIntra, 1239 pVirtioCC->pbPrevDevSpecificCfg + offIntra, 1240 RT_MIN(cb, pVirtioCC->cbDevSpecificCfg - offIntra)); 1241 1242 memcpy(pVirtioCC->pbPrevDevSpecificCfg, pVirtioCC->pbDevSpecificCfg, pVirtioCC->cbDevSpecificCfg); 1214 1243 1215 1244 if (pVirtio->fGenUpdatePending || fDevSpecificFieldChanged) … … 1229 1258 1230 1259 if (MATCHES_VIRTIO_CAP_STRUCT(off, cb, offIntra, pVirtio->LocCommonCfgCap)) 1231 return virtioCommonCfgAccessed(p Virtio, false /* fWrite */, offIntra, cb, pv);1260 return virtioCommonCfgAccessed(pDevIns, pVirtio, pVirtioCC, false /* fWrite */, offIntra, cb, pv); 1232 1261 1233 1262 if (MATCHES_VIRTIO_CAP_STRUCT(off, cb, offIntra, pVirtio->LocIsrCap) && cb == sizeof(uint8_t)) … … 1236 1265 Log6Func(("Read and clear ISR\n")); 1237 1266 pVirtio->uISR = 0; /* VirtIO specification requires reads of ISR to clear it */ 1238 virtioLowerInterrupt(p Virtio);1267 virtioLowerInterrupt(pDevIns); 1239 1268 return VINF_SUCCESS; 1240 1269 } … … 1250 1279 static DECLCALLBACK(VBOXSTRICTRC) virtioMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb) 1251 1280 { 1252 PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE); 1281 PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE); 1282 PVIRTIOSTATECC pVirtioCC = PDMINS_2_DATA_CC(pDevIns, PVIRTIOSTATECC); 1253 1283 Assert(pVirtio == (PVIRTIOSTATE)pvUser); RT_NOREF(pvUser); 1254 1284 … … 1268 1298 * Pass this MMIO write access back to the client to handle 1269 1299 */ 1270 return pVirtio ->Callbacks.pfnDevCapWrite(pDevIns, offIntra, pv, cb);1300 return pVirtioCC->Callbacks.pfnDevCapWrite(pDevIns, offIntra, pv, cb); 1271 1301 #else 1272 1302 return VINF_IOM_R3_MMIO_WRITE; … … 1275 1305 1276 1306 if (MATCHES_VIRTIO_CAP_STRUCT(off, cb, offIntra, pVirtio->LocCommonCfgCap)) 1277 return virtioCommonCfgAccessed(p Virtio, true /* fWrite */, offIntra, cb, (void *)pv);1307 return virtioCommonCfgAccessed(pDevIns, pVirtio, pVirtioCC, true /* fWrite */, offIntra, cb, (void *)pv); 1278 1308 1279 1309 if (MATCHES_VIRTIO_CAP_STRUCT(off, cb, offIntra, pVirtio->LocIsrCap) && cb == sizeof(uint8_t)) … … 1291 1321 { 1292 1322 #ifdef IN_RING3 1293 virtio r3QueueNotified(pVirtio, offIntra / VIRTIO_NOTIFY_OFFSET_MULTIPLIER, *(uint16_t *)pv);1323 virtioR3QueueNotified(pVirtio, pVirtioCC, offIntra / VIRTIO_NOTIFY_OFFSET_MULTIPLIER, *(uint16_t *)pv); 1294 1324 #else 1295 1325 return VINF_IOM_R3_MMIO_WRITE; … … 1309 1339 uint32_t uAddress, unsigned cb, uint32_t *pu32Value) 1310 1340 { 1311 PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE); 1341 PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE); 1342 PVIRTIOSTATECC pVirtioCC = PDMINS_2_DATA_CC(pDevIns, PVIRTIOSTATECC); 1312 1343 RT_NOREF(pPciDev); 1313 1344 … … 1321 1352 * (the virtio_pci_cfg_cap capability), and access data items. 1322 1353 */ 1323 uint32_t uLength = pVirtio ->pPciCfgCap->pciCap.uLength;1324 uint32_t uOffset = pVirtio ->pPciCfgCap->pciCap.uOffset;1325 uint8_t uBar = pVirtio ->pPciCfgCap->pciCap.uBar;1354 uint32_t uLength = pVirtioCC->pPciCfgCap->pciCap.uLength; 1355 uint32_t uOffset = pVirtioCC->pPciCfgCap->pciCap.uOffset; 1356 uint8_t uBar = pVirtioCC->pPciCfgCap->pciCap.uBar; 1326 1357 1327 1358 if ( (uLength != 1 && uLength != 2 && uLength != 4) … … 1348 1379 uint32_t uAddress, unsigned cb, uint32_t u32Value) 1349 1380 { 1350 PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE); 1381 PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE); 1382 PVIRTIOSTATECC pVirtioCC = PDMINS_2_DATA_CC(pDevIns, PVIRTIOSTATECC); 1351 1383 RT_NOREF(pPciDev); 1352 1384 … … 1358 1390 * (the virtio_pci_cfg_cap capability), and access data items. */ 1359 1391 1360 uint32_t uLength = pVirtio ->pPciCfgCap->pciCap.uLength;1361 uint32_t uOffset = pVirtio ->pPciCfgCap->pciCap.uOffset;1362 uint8_t uBar = pVirtio ->pPciCfgCap->pciCap.uBar;1392 uint32_t uLength = pVirtioCC->pPciCfgCap->pciCap.uLength; 1393 uint32_t uOffset = pVirtioCC->pPciCfgCap->pciCap.uOffset; 1394 uint8_t uBar = pVirtioCC->pPciCfgCap->pciCap.uBar; 1363 1395 1364 1396 if ( (uLength != 1 && uLength != 2 && uLength != 4) … … 1386 1418 * Called from the FNSSMDEVSAVEEXEC function of the device. 1387 1419 * 1388 * @param pVirtio Pointer to the virtio state.1420 * @param pVirtio Pointer to the shared virtio state. 1389 1421 * @param pHlp The ring-3 device helpers. 1390 1422 * @param pSSM The saved state handle. … … 1429 1461 * Called from the FNSSMDEVLOADEXEC function of the device. 1430 1462 * 1431 * @param pVirtio Pointer to the virtio state.1463 * @param pVirtio Pointer to the shared virtio state. 1432 1464 * @param pHlp The ring-3 device helpers. 1433 1465 * @param pSSM The saved state handle. … … 1503 1535 * This should be called from PDMDEVREGR3::pfnReset. 1504 1536 * 1505 * @param pVirtio Pointer to the virtio state. 1506 */ 1507 void virtioR3PropagateResetNotification(PVIRTIOSTATE pVirtio) 1537 * @param pDevIns The device instance. 1538 * @param pVirtio Pointer to the shared virtio state. 1539 */ 1540 void virtioR3PropagateResetNotification(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio) 1508 1541 { 1509 1542 /** @todo r=bird: You probably need to do something here. See 1510 1543 * virtioScsiR3Reset. */ 1511 RT_NOREF(p Virtio);1544 RT_NOREF(pDevIns, pVirtio); 1512 1545 } 1513 1546 … … 1521 1554 * from stalling after suspend. 1522 1555 */ 1523 void virtioR3PropagateResumeNotification(P VIRTIOSTATE pVirtio)1524 { 1525 virtioNotifyGuestDriver(p Virtio, (uint16_t)0 /* idxQueue */, true /* fForce */);1556 void virtioR3PropagateResumeNotification(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio) 1557 { 1558 virtioNotifyGuestDriver(pDevIns, pVirtio, 0 /* idxQueue */, true /* fForce */); 1526 1559 } 1527 1560 … … 1530 1563 * This should be called from PDMDEVREGR3::pfnDestruct. 1531 1564 * 1532 * @param pVirtio Pointer to the virtio state.1533 1565 * @param pDevIns The device instance. 1534 */ 1535 void virtioR3Term(PVIRTIOSTATE pVirtio, PPDMDEVINS pDevIns) 1536 { 1537 if (pVirtio->pvPrevDevSpecificCfg) 1538 { 1539 RTMemFree(pVirtio->pvPrevDevSpecificCfg); 1540 pVirtio->pvPrevDevSpecificCfg = NULL; 1541 } 1542 RT_NOREF(pDevIns); 1566 * @param pVirtio Pointer to the shared virtio state. 1567 * @param pVirtioCC Pointer to the ring-3 virtio state. 1568 */ 1569 void virtioR3Term(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC) 1570 { 1571 if (pVirtioCC->pbPrevDevSpecificCfg) 1572 { 1573 RTMemFree(pVirtioCC->pbPrevDevSpecificCfg); 1574 pVirtioCC->pbPrevDevSpecificCfg = NULL; 1575 } 1576 RT_NOREF(pDevIns, pVirtio); 1543 1577 } 1544 1578 … … 1549 1583 * This should be called from PDMDEVREGR3::pfnConstruct. 1550 1584 * 1551 * @param pVirtio Pointer to the virtio state. This must be1552 * the first member in the shared device1553 * instance data!1554 1585 * @param pDevIns The device instance. 1586 * @param pVirtio Pointer to the shared virtio state. This 1587 * must be the first member in the shared 1588 * device instance data! 1589 * @param pVirtioCC Pointer to the ring-3 virtio state. This 1590 * must be the first member in the ring-3 1591 * device instance data! 1555 1592 * @param pPciParams Values to populate industry standard PCI Configuration Space data structure 1556 1593 * @param pcszInstance Device instance name (format-specifier) … … 1561 1598 * configuration struct. 1562 1599 */ 1563 int virtioR3Init(P VIRTIOSTATE pVirtio, PPDMDEVINS pDevIns, PVIRTIOPCIPARAMS pPciParams, const char *pcszInstance,1564 uint64_t fDevSpecificFeatures, void *pvDevSpecificCfg, uint16_t cbDevSpecificCfg)1600 int virtioR3Init(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC, PVIRTIOPCIPARAMS pPciParams, 1601 const char *pcszInstance, uint64_t fDevSpecificFeatures, void *pvDevSpecificCfg, uint16_t cbDevSpecificCfg) 1565 1602 { 1566 1603 /* … … 1569 1606 */ 1570 1607 AssertLogRelReturn(pVirtio == PDMINS_2_DATA(pDevIns, PVIRTIOSTATE), VERR_STATE_CHANGED); 1608 AssertLogRelReturn(pVirtioCC == PDMINS_2_DATA_CC(pDevIns, PVIRTIOSTATECC), VERR_STATE_CHANGED); 1571 1609 1572 1610 … … 1587 1625 RTStrCopy(pVirtio->szInstance, sizeof(pVirtio->szInstance), pcszInstance); 1588 1626 1589 pVirtio->pDevInsR3 = pDevIns;1590 1627 pVirtio->uDeviceStatus = 0; 1591 pVirtio ->cbDevSpecificCfg = cbDevSpecificCfg;1592 pVirtio ->pvDevSpecificCfg =pvDevSpecificCfg;1593 pVirtio ->pvPrevDevSpecificCfg =RTMemDup(pvDevSpecificCfg, cbDevSpecificCfg);1594 AssertLogRelReturn(pVirtio ->pvPrevDevSpecificCfg, VERR_NO_MEMORY);1628 pVirtioCC->cbDevSpecificCfg = cbDevSpecificCfg; 1629 pVirtioCC->pbDevSpecificCfg = (uint8_t *)pvDevSpecificCfg; 1630 pVirtioCC->pbPrevDevSpecificCfg = (uint8_t *)RTMemDup(pvDevSpecificCfg, cbDevSpecificCfg); 1631 AssertLogRelReturn(pVirtioCC->pbPrevDevSpecificCfg, VERR_NO_MEMORY); 1595 1632 1596 1633 /* Set PCI config registers (assume 32-bit mode) */ … … 1649 1686 cbRegion += pCfg->uLength; 1650 1687 SET_PCI_CAP_LOC(pPciDev, pCfg, pVirtio->LocCommonCfgCap, 2); 1651 pVirtio ->pCommonCfgCap = pCfg;1688 pVirtioCC->pCommonCfgCap = pCfg; 1652 1689 1653 1690 /* … … 1661 1698 pCfg->uCapNext = CFG_ADDR_2_IDX(pCfg) + pCfg->uCapLen; 1662 1699 pCfg->uBar = VIRTIO_REGION_PCI_CAP; 1663 pCfg->uOffset = pVirtio ->pCommonCfgCap->uOffset + pVirtio->pCommonCfgCap->uLength;1700 pCfg->uOffset = pVirtioCC->pCommonCfgCap->uOffset + pVirtioCC->pCommonCfgCap->uLength; 1664 1701 pCfg->uOffset = RT_ALIGN_32(pCfg->uOffset, 2); /** @todo r=bird: Why is this word aligned rather than dword? If there is a 1665 1702 * theoretical chance we won't allways be on a dword boundrary here, the … … 1668 1705 cbRegion += pCfg->uLength; 1669 1706 SET_PCI_CAP_LOC(pPciDev, pCfg, pVirtio->LocNotifyCap, 1); 1670 pVirtio ->pNotifyCap = (PVIRTIO_PCI_NOTIFY_CAP_T)pCfg;1671 pVirtio ->pNotifyCap->uNotifyOffMultiplier = VIRTIO_NOTIFY_OFFSET_MULTIPLIER;1707 pVirtioCC->pNotifyCap = (PVIRTIO_PCI_NOTIFY_CAP_T)pCfg; 1708 pVirtioCC->pNotifyCap->uNotifyOffMultiplier = VIRTIO_NOTIFY_OFFSET_MULTIPLIER; 1672 1709 1673 1710 /* ISR capability (VirtIO 1.0 spec, section 4.1.4.5) … … 1683 1720 pCfg->uCapNext = CFG_ADDR_2_IDX(pCfg) + pCfg->uCapLen; 1684 1721 pCfg->uBar = VIRTIO_REGION_PCI_CAP; 1685 pCfg->uOffset = pVirtio ->pNotifyCap->pciCap.uOffset + pVirtio->pNotifyCap->pciCap.uLength; /** @todo r=bird: This probably is _not_ dword aligned, given that the previous structure is 0x32 (50) bytes long. */1722 pCfg->uOffset = pVirtioCC->pNotifyCap->pciCap.uOffset + pVirtioCC->pNotifyCap->pciCap.uLength; /** @todo r=bird: This probably is _not_ dword aligned, given that the previous structure is 0x32 (50) bytes long. */ 1686 1723 pCfg->uLength = sizeof(uint8_t); 1687 1724 cbRegion += pCfg->uLength; 1688 1725 SET_PCI_CAP_LOC(pPciDev, pCfg, pVirtio->LocIsrCap, 4); 1689 pVirtio ->pIsrCap = pCfg;1726 pVirtioCC->pIsrCap = pCfg; 1690 1727 1691 1728 /* PCI Cfg capability (VirtIO 1.0 spec, section 4.1.4.7) … … 1701 1738 pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR; 1702 1739 pCfg->uCapLen = sizeof(VIRTIO_PCI_CFG_CAP_T); 1703 pCfg->uCapNext = (pVirtio->fMsiSupport || pVirtio ->pvDevSpecificCfg) ? CFG_ADDR_2_IDX(pCfg) + pCfg->uCapLen : 0;1740 pCfg->uCapNext = (pVirtio->fMsiSupport || pVirtioCC->pbDevSpecificCfg) ? CFG_ADDR_2_IDX(pCfg) + pCfg->uCapLen : 0; 1704 1741 pCfg->uBar = 0; 1705 1742 pCfg->uOffset = 0; … … 1707 1744 cbRegion += pCfg->uLength; 1708 1745 SET_PCI_CAP_LOC(pPciDev, pCfg, pVirtio->LocPciCfgCap, 1); 1709 pVirtio ->pPciCfgCap = (PVIRTIO_PCI_CFG_CAP_T)pCfg;1710 1711 if (pVirtio ->pvDevSpecificCfg)1746 pVirtioCC->pPciCfgCap = (PVIRTIO_PCI_CFG_CAP_T)pCfg; 1747 1748 if (pVirtioCC->pbDevSpecificCfg) 1712 1749 { 1713 1750 /* Following capability (via VirtIO 1.0, section 4.1.4.6). Client defines the … … 1719 1756 pCfg->uCapNext = pVirtio->fMsiSupport ? CFG_ADDR_2_IDX(pCfg) + pCfg->uCapLen : 0; 1720 1757 pCfg->uBar = VIRTIO_REGION_PCI_CAP; 1721 pCfg->uOffset = pVirtio ->pIsrCap->uOffset + pVirtio->pIsrCap->uLength;1758 pCfg->uOffset = pVirtioCC->pIsrCap->uOffset + pVirtioCC->pIsrCap->uLength; 1722 1759 pCfg->uOffset = RT_ALIGN_32(pCfg->uOffset, 4); 1723 1760 pCfg->uLength = cbDevSpecificCfg; 1724 1761 cbRegion += pCfg->uLength; 1725 1762 SET_PCI_CAP_LOC(pPciDev, pCfg, pVirtio->LocDeviceCap, 4); 1726 //pVirtio->pDeviceCap = pCfg;1763 pVirtioCC->pDeviceCap = pCfg; 1727 1764 } 1728 1765 else … … 1774 1811 * 1775 1812 * @returns VBox status code. 1776 * @param pVirtio Pointer to the virtio state. This must be the first1813 * @param pVirtio Pointer to the shared virtio state. This must be the first 1777 1814 * member in the shared device instance data! 1778 1815 * @param pDevIns The device instance. -
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.h
r81662 r81675 25 25 #include <iprt/sg.h> 26 26 27 /** Pointer to the virt i/ostate. */27 /** Pointer to the shared VirtIO state. */ 28 28 typedef struct VIRTIOSTATE *PVIRTIOSTATE; 29 /** Pointer to the ring-3 VirtIO state. */ 30 typedef struct VIRTIOSTATER3 *PVIRTIOSTATER3; 31 /** Pointer to the ring-0 VirtIO state. */ 32 typedef struct VIRTIOSTATER0 *PVIRTIOSTATER0; 33 /** Pointer to the raw-mode VirtIO state. */ 34 typedef struct VIRTIOSTATERC *PVIRTIOSTATERC; 35 /** Pointer to the instance data for the current context. */ 36 typedef CTX_SUFF(PVIRTIOSTATE) PVIRTIOSTATECC; 37 29 38 30 39 /** … … 101 110 * changes. 102 111 * 103 * @param pVirtio Pointer to virtio state. 112 * @param pVirtio Pointer to the shared virtio state. 113 * @param pVirtioCC Pointer to the ring-3 virtio state. 104 114 * @param fDriverOk True if guest driver is okay (thus queues, etc... are 105 115 * valid) 106 116 */ 107 DECLCALLBACKMEMBER(void, pfnStatusChanged)(PVIRTIOSTATE pVirtio, uint32_t fDriverOk);117 DECLCALLBACKMEMBER(void, pfnStatusChanged)(PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC, uint32_t fDriverOk); 108 118 109 119 /** … … 111 121 * that the avail queue has buffers, and this callback informs the client. 112 122 * 113 * @param pVirtio Pointer to virtio state. 123 * @param pVirtio Pointer to the shared virtio state. 124 * @param pVirtioCC Pointer to the ring-3 virtio state. 114 125 * @param idxQueue Index of the notified queue 115 126 */ 116 DECLCALLBACKMEMBER(void, pfnQueueNotified)(PVIRTIOSTATE pVirtio, uint16_t idxQueue);127 DECLCALLBACKMEMBER(void, pfnQueueNotified)(PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC, uint16_t idxQueue); 117 128 118 129 /** … … 254 265 255 266 /** 256 * The core (/common) state of the VirtIO PCI device267 * The core/common state of the VirtIO PCI devices, shared edition. 257 268 */ 258 269 typedef struct VIRTIOSTATE 259 270 { 260 271 char szInstance[16]; /**< Instance name, e.g. "VIRTIOSCSI0" */ 261 PPDMDEVINSR3 pDevInsR3; /**< Device instance - R3 */262 263 #if 0264 RTGCPHYS GCPhysPciCapBase; /**< Pointer to MMIO mapped capability data */265 RTGCPHYS GCPhysCommonCfg; /**< Pointer to MMIO mapped capability data */266 RTGCPHYS GCPhysNotifyCap; /**< Pointer to MMIO mapped capability data */267 RTGCPHYS GCPhysIsrCap; /**< Pointer to MMIO mapped capability data */268 RTGCPHYS GCPhysDeviceCap; /**< Pointer to MMIO mapped capability data */269 #endif270 272 271 273 RTGCPHYS aGCPhysQueueDesc[VIRTQ_MAX_CNT]; /**< (MMIO) PhysAdr per-Q desc structs GUEST */ … … 293 295 294 296 VIRTQSTATE virtqState[VIRTQ_MAX_CNT]; /**< Local impl-specific queue context */ 295 VIRTIOCALLBACKS Callbacks; /**< Callback vectors to client */296 297 R3PTRTYPE(PVIRTIO_PCI_CFG_CAP_T) pPciCfgCap; /**< Pointer to struct in the PCI configuration area. */298 R3PTRTYPE(PVIRTIO_PCI_NOTIFY_CAP_T) pNotifyCap; /**< Pointer to struct in the PCI configuration area. */299 R3PTRTYPE(PVIRTIO_PCI_CAP_T) pCommonCfgCap; /**< Pointer to struct in the PCI configuration area. */300 R3PTRTYPE(PVIRTIO_PCI_CAP_T) pIsrCap; /**< Pointer to struct in the PCI configuration area. */301 R3PTRTYPE(PVIRTIO_PCI_CAP_T) pDeviceCap; /**< Pointer to struct in the PCI configuration area. */302 297 303 298 /** @name The locations of the capability structures in PCI config space and the BAR. … … 310 305 /** @} */ 311 306 312 uint32_t cbDevSpecificCfg; /**< Size of client's dev-specific config data */313 void *pvDevSpecificCfg; /**< Pointer to client's struct */314 void *pvPrevDevSpecificCfg; /**< Previous read dev-specific cfg of client */315 307 bool fGenUpdatePending; /**< If set, update cfg gen after driver reads */ 316 308 uint8_t uPciCfgDataOff; … … 324 316 325 317 318 /** 319 * The core/common state of the VirtIO PCI devices, ring-3 edition. 320 */ 321 typedef struct VIRTIOSTATER3 322 { 323 VIRTIOCALLBACKS Callbacks; /**< Callback vectors to client */ 324 325 R3PTRTYPE(PVIRTIO_PCI_CFG_CAP_T) pPciCfgCap; /**< Pointer to struct in the PCI configuration area. */ 326 R3PTRTYPE(PVIRTIO_PCI_NOTIFY_CAP_T) pNotifyCap; /**< Pointer to struct in the PCI configuration area. */ 327 R3PTRTYPE(PVIRTIO_PCI_CAP_T) pCommonCfgCap; /**< Pointer to struct in the PCI configuration area. */ 328 R3PTRTYPE(PVIRTIO_PCI_CAP_T) pIsrCap; /**< Pointer to struct in the PCI configuration area. */ 329 R3PTRTYPE(PVIRTIO_PCI_CAP_T) pDeviceCap; /**< Pointer to struct in the PCI configuration area. */ 330 331 uint32_t cbDevSpecificCfg; /**< Size of client's dev-specific config data */ 332 R3PTRTYPE(uint8_t *) pbDevSpecificCfg; /**< Pointer to client's struct */ 333 R3PTRTYPE(uint8_t *) pbPrevDevSpecificCfg; /**< Previous read dev-specific cfg of client */ 334 bool fGenUpdatePending; /**< If set, update cfg gen after driver reads */ 335 } VIRTIOSTATER3; 336 337 338 /** 339 * The core/common state of the VirtIO PCI devices, ring-0 edition. 340 */ 341 typedef struct VIRTIOSTATER0 342 { 343 uint64_t uUnusedAtTheMoment; 344 } VIRTIOSTATER0; 345 346 347 /** 348 * The core/common state of the VirtIO PCI devices, raw-mode edition. 349 */ 350 typedef struct VIRTIOSTATERC 351 { 352 uint64_t uUnusedAtTheMoment; 353 } VIRTIOSTATERC; 354 355 356 /** @typedef VIRTIOSTATECC 357 * The instance data for the current context. */ 358 typedef CTX_SUFF(VIRTIOSTATE) VIRTIOSTATECC; 359 360 326 361 /** virtq related flags */ 327 362 #define VIRTQ_DESC_F_NEXT 1 /**< Indicates this descriptor chains to next */ … … 346 381 int virtioQueueDetach(PVIRTIOSTATE pVirtio, uint16_t idxQueue); 347 382 #endif 348 int virtioR3QueueGet(PVIRTIOSTATE pVirtio, uint16_t idxQueue, PPVIRTIO_DESC_CHAIN_T ppDescChain, bool fRemove); 349 int virtioR3QueuePut(PVIRTIOSTATE pVirtio, uint16_t idxQueue, PRTSGBUF pSgVirtReturn, 383 int virtioR3QueueGet(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, 384 PPVIRTIO_DESC_CHAIN_T ppDescChain, bool fRemove); 385 int virtioR3QueuePut(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue, PRTSGBUF pSgVirtReturn, 350 386 PVIRTIO_DESC_CHAIN_T pDescChain, bool fFence); 351 352 int virtioQueueSync(PVIRTIOSTATE pVirtio, uint16_t idxQueue); 353 bool virtioQueueIsEmpty(PVIRTIOSTATE pVirtio, uint16_t idxQueue); 354 387 int virtioQueueSync(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue); 388 bool virtioQueueIsEmpty(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, uint16_t idxQueue); 355 389 void virtioQueueEnable(PVIRTIOSTATE pVirtio, uint16_t idxQueue, bool fEnabled); 390 391 #if 0 /** @todo unused */ 356 392 void virtioResetAll(PVIRTIOSTATE pVirtio); 393 #endif 357 394 358 395 /** … … 409 446 int virtioR3SaveExec(PVIRTIOSTATE pVirtio, PCPDMDEVHLPR3 pHlp, PSSMHANDLE pSSM); 410 447 int virtioR3LoadExec(PVIRTIOSTATE pVirtio, PCPDMDEVHLPR3 pHlp, PSSMHANDLE pSSM); 411 void virtioR3PropagateResetNotification(P VIRTIOSTATE pVirtio);412 void virtioR3PropagateResumeNotification(P VIRTIOSTATE pVirtio);413 void virtioR3Term(P VIRTIOSTATE pVirtio, PPDMDEVINS pDevIns);414 int virtioR3Init(P VIRTIOSTATE pVirtio, PPDMDEVINS pDevIns, PVIRTIOPCIPARAMS pPciParams, const char *pcszInstance,415 uint64_t fDevSpecificFeatures, void *pvDevSpecificCfg, uint16_t cbDevSpecificCfg);448 void virtioR3PropagateResetNotification(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio); 449 void virtioR3PropagateResumeNotification(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio); 450 void virtioR3Term(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC); 451 int virtioR3Init(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, PVIRTIOSTATECC pVirtioCC, PVIRTIOPCIPARAMS pPciParams, 452 const char *pcszInstance, uint64_t fDevSpecificFeatures, void *pvDevSpecificCfg, uint16_t cbDevSpecificCfg); 416 453 417 454 void virtioLogMappedIoValue(const char *pszFunc, const char *pszMember, uint32_t uMemberSize,
Note:
See TracChangeset
for help on using the changeset viewer.