Changeset 84803 in vbox for trunk/src/VBox/Devices/Storage
- Timestamp:
- Jun 12, 2020 6:17:35 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp
r84786 r84803 81 81 #define VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED VIRTIOSCSI_HOST_SCSI_FEATURES_NONE 82 82 83 #define VIRTIOSCSI_REQ_ QUEUE_CNT 4 /**< T.B.D. Consider increasing */84 #define VIRTIOSCSI_ QUEUE_CNT (VIRTIOSCSI_REQ_QUEUE_CNT + 2)83 #define VIRTIOSCSI_REQ_VIRTQ_CNT 4 /**< T.B.D. Consider increasing */ 84 #define VIRTIOSCSI_VIRTQ_CNT (VIRTIOSCSI_REQ_VIRTQ_CNT + 2) 85 85 #define VIRTIOSCSI_MAX_TARGETS 256 /**< T.B.D. Figure out a a good value for this. */ 86 86 #define VIRTIOSCSI_MAX_LUN 256 /**< VirtIO specification, section 5.6.4 */ … … 112 112 #define VIRTQ_REQ_BASE 2 /**< Spec-defined base index of request queues */ 113 113 114 #define VIRTQNAME(idx Queue) (pThis->aszVirtqNames[idxQueue]) /**< Macro to get queue name from its index */115 #define CBVIRTQNAME(idx Queue) RTStrNLen(VIRTQNAME(idxQueue), sizeof(VIRTQNAME(idxQueue)))116 117 #define IS_REQ_ QUEUE(idxQueue) (idxQueue >= VIRTQ_REQ_BASE && idxQueue < VIRTIOSCSI_QUEUE_CNT)114 #define VIRTQNAME(idxVirtq) (pThis->aszVirtqNames[idxVirtq]) /**< Macro to get queue name from its index */ 115 #define CBVIRTQNAME(idxVirtq) RTStrNLen(VIRTQNAME(idxVirtq), sizeof(VIRTQNAME(idxVirtq))) 116 117 #define IS_REQ_VIRTQ(idxVirtq) (idxVirtq >= VIRTQ_REQ_BASE && idxVirtq < VIRTIOSCSI_VIRTQ_CNT) 118 118 119 119 #define VIRTIO_IS_IN_DIRECTION(pMediaExTxDirEnumValue) \ … … 123 123 ((pMediaExTxDirEnumValue) == PDMMEDIAEXIOREQSCSITXDIR_TO_DEVICE) 124 124 125 #define IS_VIRTQ_EMPTY(pDevIns, pVirtio, idx Queue) \126 (virtioCore QueueAvailCount(pDevIns, pVirtio, idxQueue) == 0)125 #define IS_VIRTQ_EMPTY(pDevIns, pVirtio, idxVirtq) \ 126 (virtioCoreVirtqAvailCount(pDevIns, pVirtio, idxVirtq) == 0) 127 127 128 128 … … 137 137 typedef struct virtio_scsi_config 138 138 { 139 uint32_t uNum Queues; /**< num_queues \# of req q's exposed by dev */139 uint32_t uNumVirtqs; /**< num_queues \# of req q's exposed by dev */ 140 140 uint32_t uSegMax; /**< seg_max Max \# of segs allowed in cmd */ 141 141 uint32_t uMaxSectors; /**< max_sectors Hint to guest max xfer to use */ … … 427 427 428 428 /** Per device-bound virtq worker-thread contexts (eventq slot unused) */ 429 VIRTIOSCSIWORKER aWorkers[VIRTIOSCSI_ QUEUE_CNT];429 VIRTIOSCSIWORKER aWorkers[VIRTIOSCSI_VIRTQ_CNT]; 430 430 431 431 /** Instance name */ … … 433 433 434 434 /** Device-specific spec-based VirtIO VIRTQNAMEs */ 435 char aszVirtqNames[VIRTIOSCSI_ QUEUE_CNT][VIRTIO_MAX_QUEUE_NAME_SIZE];435 char aszVirtqNames[VIRTIOSCSI_VIRTQ_CNT][VIRTIO_MAX_VIRTQ_NAME_SIZE]; 436 436 437 437 /** Track which VirtIO queues we've attached to */ 438 bool af QueueAttached[VIRTIOSCSI_QUEUE_CNT];438 bool afVirtqAttached[VIRTIOSCSI_VIRTQ_CNT]; 439 439 440 440 /** Set if events missed due to lack of bufs avail on eventq */ … … 488 488 489 489 /** Per device-bound virtq worker-thread contexts (eventq slot unused) */ 490 VIRTIOSCSIWORKERR3 aWorkers[VIRTIOSCSI_ QUEUE_CNT];490 VIRTIOSCSIWORKERR3 aWorkers[VIRTIOSCSI_VIRTQ_CNT]; 491 491 492 492 /** Device base interface. */ … … 503 503 R3PTRTYPE(PPDMIMEDIANOTIFY) pMediaNotify; 504 504 505 /** Queueto send tasks to R3. - HC ptr */506 R3PTRTYPE(PPDMQUEUE) pNotifier QueueR3;505 /** Virtq to send tasks to R3. - HC ptr */ 506 R3PTRTYPE(PPDMQUEUE) pNotifierVirtqR3; 507 507 508 508 /** True if in the process of quiescing I/O */ … … 557 557 PDMMEDIAEXIOREQ hIoReq; /**< Handle of I/O request */ 558 558 PVIRTIOSCSITARGET pTarget; /**< Target */ 559 uint16_t idx Queue; /**< Index of queue this request arrived on */559 uint16_t idxVirtq; /**< Index of queue this request arrived on */ 560 560 PVIRTIO_DESC_CHAIN_T pDescChain; /**< Prepared desc chain pulled from virtq avail ring */ 561 561 size_t cbDataIn; /**< size of dataout buffer */ … … 573 573 574 574 /** 575 * callback_method_impl{VIRTIOCORER0,pfn QueueNotified}575 * callback_method_impl{VIRTIOCORER0,pfnVirtqNotified} 576 576 * @todo this causes burn if I prefix with at-sign. This callback is in VIRTIOCORER0 and VIRTIOCORER3 577 577 */ 578 static DECLCALLBACK(void) virtioScsiNotified(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue)578 static DECLCALLBACK(void) virtioScsiNotified(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq) 579 579 { 580 580 … … 582 582 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 583 583 584 AssertReturnVoid(idx Queue < VIRTIOSCSI_QUEUE_CNT);585 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[idx Queue];584 AssertReturnVoid(idxVirtq < VIRTIOSCSI_VIRTQ_CNT); 585 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[idxVirtq]; 586 586 587 587 #if defined (IN_RING3) && defined (LOG_ENABLED) … … 589 589 #endif 590 590 591 if (idx Queue == CONTROLQ_IDX || IS_REQ_QUEUE(idxQueue))592 { 593 Log6Func(("%s has available data\n", VIRTQNAME(idx Queue)));591 if (idxVirtq == CONTROLQ_IDX || IS_REQ_VIRTQ(idxVirtq)) 592 { 593 Log6Func(("%s has available data\n", VIRTQNAME(idxVirtq))); 594 594 /* Wake queue's worker thread up if sleeping */ 595 595 if (!ASMAtomicXchgBool(&pWorker->fNotified, true)) … … 597 597 if (ASMAtomicReadBool(&pWorker->fSleeping)) 598 598 { 599 Log6Func(("waking %s worker.\n", VIRTQNAME(idx Queue)));599 Log6Func(("waking %s worker.\n", VIRTQNAME(idxVirtq))); 600 600 int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pWorker->hEvtProcess); 601 601 AssertRC(rc); … … 603 603 } 604 604 } 605 else if (idx Queue== EVENTQ_IDX)606 { 607 Log3Func(("Driver queued buffer(s) to %s\n", VIRTQNAME(idx Queue)));605 else if (idxVirtq == EVENTQ_IDX) 606 { 607 Log3Func(("Driver queued buffer(s) to %s\n", VIRTQNAME(idxVirtq))); 608 608 // if (ASMAtomicXchgBool(&pThis->fEventsMissed, false)) 609 609 // virtioScsiR3ReportEventsMissed(pDevIns, pThis, 0); 610 610 } 611 611 else 612 LogFunc(("Unexpected queue idx (ignoring): %d\n", idx Queue));612 LogFunc(("Unexpected queue idx (ignoring): %d\n", idxVirtq)); 613 613 } 614 614 … … 619 619 DECLINLINE(void) virtioScsiSetVirtqNames(PVIRTIOSCSI pThis) 620 620 { 621 RTStrCopy(pThis->aszVirtqNames[CONTROLQ_IDX], VIRTIO_MAX_ QUEUE_NAME_SIZE, "controlq");622 RTStrCopy(pThis->aszVirtqNames[EVENTQ_IDX], VIRTIO_MAX_ QUEUE_NAME_SIZE, "eventq");623 for (uint16_t idx Queue = VIRTQ_REQ_BASE; idxQueue < VIRTQ_REQ_BASE + VIRTIOSCSI_REQ_QUEUE_CNT; idxQueue++)624 RTStrPrintf(pThis->aszVirtqNames[idx Queue], VIRTIO_MAX_QUEUE_NAME_SIZE,625 "requestq<%d>", idx Queue- VIRTQ_REQ_BASE);621 RTStrCopy(pThis->aszVirtqNames[CONTROLQ_IDX], VIRTIO_MAX_VIRTQ_NAME_SIZE, "controlq"); 622 RTStrCopy(pThis->aszVirtqNames[EVENTQ_IDX], VIRTIO_MAX_VIRTQ_NAME_SIZE, "eventq"); 623 for (uint16_t idxVirtq = VIRTQ_REQ_BASE; idxVirtq < VIRTQ_REQ_BASE + VIRTIOSCSI_REQ_VIRTQ_CNT; idxVirtq++) 624 RTStrPrintf(pThis->aszVirtqNames[idxVirtq], VIRTIO_MAX_VIRTQ_NAME_SIZE, 625 "requestq<%d>", idxVirtq - VIRTQ_REQ_BASE); 626 626 } 627 627 … … 755 755 756 756 PVIRTIO_DESC_CHAIN_T pDescChain = NULL; 757 int rc = virtioCoreR3 QueueGet(pDevIns, &pThis->Virtio, EVENTQ_IDX, &pDescChain, true);757 int rc = virtioCoreR3VirtqGet(pDevIns, &pThis->Virtio, EVENTQ_IDX, &pDescChain, true); 758 758 if (rc == VERR_NOT_AVAILABLE) 759 759 { … … 783 783 RTSgBufInit(&ReqSgBuf, aReqSegs, RT_ELEMENTS(aReqSegs)); 784 784 785 rc = virtioCoreR3 QueuePut(pDevIns, &pThis->Virtio, EVENTQ_IDX, &ReqSgBuf, pDescChain, true /*fFence*/);785 rc = virtioCoreR3VirtqPut(pDevIns, &pThis->Virtio, EVENTQ_IDX, &ReqSgBuf, pDescChain, true /*fFence*/); 786 786 if (rc == VINF_SUCCESS) 787 virtioCore QueueSync(pDevIns, &pThis->Virtio, EVENTQ_IDX, false);787 virtioCoreVirtqSync(pDevIns, &pThis->Virtio, EVENTQ_IDX, false); 788 788 else 789 789 LogRel(("Error writing control message to guest\n")); … … 811 811 * @param pThis VirtIO SCSI shared instance data. 812 812 * @param pThisCC VirtIO SCSI ring-3 instance data. 813 * @param idx Queue Queueindex813 * @param idxVirtq Virtq index 814 814 * @param pDescChain Pointer to pre-processed descriptor chain pulled from virtq 815 815 * @param pRespHdr Response header … … 819 819 * @returns VINF_SUCCESS 820 820 */ 821 static int virtioScsiR3ReqErr(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, uint16_t idx Queue,821 static int virtioScsiR3ReqErr(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, uint16_t idxVirtq, 822 822 PVIRTIO_DESC_CHAIN_T pDescChain, REQ_RESP_HDR_T *pRespHdr, uint8_t *pbSense, 823 823 size_t cbSenseCfg) … … 853 853 pRespHdr->uResponse = VIRTIOSCSI_S_RESET; 854 854 855 virtioCoreR3 QueuePut(pDevIns, &pThis->Virtio, idxQueue, &ReqSgBuf, pDescChain, true /* fFence */);856 virtioCore QueueSync(pDevIns, &pThis->Virtio, idxQueue);855 virtioCoreR3VirtqPut(pDevIns, &pThis->Virtio, idxVirtq, &ReqSgBuf, pDescChain, true /* fFence */); 856 virtioCoreVirtqSync(pDevIns, &pThis->Virtio, idxVirtq); 857 857 858 858 if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThisCC->fQuiescing) … … 872 872 * @param pThis VirtIO SCSI shared instance data. 873 873 * @param pThisCC VirtIO SCSI ring-3 instance data. 874 * @param idx Queue Queueindex874 * @param idxVirtq Virtq index 875 875 * @param pDescChain Pointer to pre-processed descriptor chain pulled from virtq 876 876 * @param cbResidual The number of residual bytes or something like that. … … 883 883 * @returns VINF_SUCCESS 884 884 */ 885 static int virtioScsiR3ReqErr4(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, uint16_t idx Queue,885 static int virtioScsiR3ReqErr4(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, uint16_t idxVirtq, 886 886 PVIRTIO_DESC_CHAIN_T pDescChain, size_t cbResidual, uint8_t bStatus, uint8_t bResponse, 887 887 uint8_t *pbSense, size_t cbSense, size_t cbSenseCfg) … … 894 894 RespHdr.uResponse = bResponse; 895 895 896 return virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, idx Queue, pDescChain, &RespHdr, pbSense, cbSenseCfg);896 return virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, idxVirtq, pDescChain, &RespHdr, pbSense, cbSenseCfg); 897 897 } 898 898 … … 1016 1016 respHdr.uResidual = pReq->cbDataIn & UINT32_MAX; 1017 1017 1018 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, pReq->idx Queue, pReq->pDescChain, &respHdr, abSense,1018 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, pReq->idxVirtq, pReq->pDescChain, &respHdr, abSense, 1019 1019 RT_MIN(pThis->virtioScsiConfig.uSenseSize, VIRTIOSCSI_SENSE_SIZE_MAX)); 1020 1020 } … … 1042 1042 VERR_BUFFER_OVERFLOW); 1043 1043 1044 virtioCoreR3 QueuePut(pDevIns, &pThis->Virtio, pReq->idxQueue, &ReqSgBuf, pReq->pDescChain, true /* fFence TBD */);1045 virtioCore QueueSync(pDevIns, &pThis->Virtio, pReq->idxQueue);1044 virtioCoreR3VirtqPut(pDevIns, &pThis->Virtio, pReq->idxVirtq, &ReqSgBuf, pReq->pDescChain, true /* fFence TBD */); 1045 virtioCoreVirtqSync(pDevIns, &pThis->Virtio, pReq->idxVirtq); 1046 1046 1047 1047 Log2(("-----------------------------------------------------------------------------------------\n")); … … 1058 1058 /** 1059 1059 * @interface_method_impl{PDMIMEDIAEXPORT,pfnIoReqCopyFromBuf} 1060 * 1060 1061 1061 * Copy virtual memory from VSCSI layer to guest physical memory 1062 1062 */ … … 1144 1144 */ 1145 1145 static int virtioScsiR3ReqSubmit(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, 1146 uint16_t idx Queue, PVIRTIO_DESC_CHAIN_T pDescChain)1146 uint16_t idxVirtq, PVIRTIO_DESC_CHAIN_T pDescChain) 1147 1147 { 1148 1148 … … 1194 1194 if (uType == 0xc1 && uTarget == 0x01) 1195 1195 { 1196 LogRel(("* * * REPORT LUNS LU ACCESSED* * * "));1196 LogRel(("* * * WARNING: REPORT LUNS LU ACCESSED. FEATURE NOT IMPLEMENTED SEE DevVirtioScsi.cpp * * * ")); 1197 1197 /* Force rejection. */ /** @todo figure out right way to handle. Note this is a very 1198 1198 * vague and confusing part of the VirtIO spec (which deviates from the SCSI standard). 1199 1199 * I have not been able to determine how to implement this properly. I've checked the 1200 * source code of Guest drivers, and so far none seem to use it. If logs show1201 * this warning, implementing it can be re-visited */1200 * source code of Guest drivers, and so far none seem to use it. If this message is logged, 1201 * meaning a guest expects this feature, implementing it can be re-visited */ 1202 1202 uScsiLun = 0xff; 1203 1203 } … … 1232 1232 { 1233 1233 Log2Func(("Error submitting request, bad LUN format\n")); 1234 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idx Queue, pDescChain, cbDataIn + cbDataOut, 0 /*bStatus*/,1234 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idxVirtq, pDescChain, cbDataIn + cbDataOut, 0 /*bStatus*/, 1235 1235 VIRTIOSCSI_S_FAILURE, NULL /*pbSense*/, 0 /*cbSense*/, cbSenseCfg); 1236 1236 } … … 1247 1247 0, SCSI_SENSE_ILLEGAL_REQUEST, 1248 1248 0, 0, 0, 0, 10, SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED, 0, 0 }; 1249 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idx Queue, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_CHECK_CONDITION,1249 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idxVirtq, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_CHECK_CONDITION, 1250 1250 VIRTIOSCSI_S_BAD_TARGET, abSense, sizeof(abSense), cbSenseCfg); 1251 1251 } … … 1258 1258 0, SCSI_SENSE_ILLEGAL_REQUEST, 1259 1259 0, 0, 0, 0, 10, SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED, 0, 0 }; 1260 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idx Queue, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_CHECK_CONDITION,1260 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idxVirtq, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_CHECK_CONDITION, 1261 1261 VIRTIOSCSI_S_OK, abSense, sizeof(abSense), cbSenseCfg); 1262 1262 } … … 1266 1266 { 1267 1267 Log2Func(("Aborting req submission because reset is in progress\n")); 1268 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idx Queue, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_OK,1268 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idxVirtq, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_OK, 1269 1269 VIRTIOSCSI_S_RESET, NULL /*pbSense*/, 0 /*cbSense*/, cbSenseCfg); 1270 1270 } … … 1277 1277 uint8_t abSense[] = { RT_BIT(7) | SCSI_SENSE_RESPONSE_CODE_CURR_FIXED, 1278 1278 0, SCSI_SENSE_ILLEGAL_REQUEST, 0, 0, 0, 0, 10, 0, 0, 0 }; 1279 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idx Queue, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_CHECK_CONDITION,1279 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idxVirtq, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_CHECK_CONDITION, 1280 1280 VIRTIOSCSI_S_FAILURE, abSense, sizeof(abSense), cbSenseCfg); 1281 1281 } … … 1295 1295 pReq->hIoReq = hIoReq; 1296 1296 pReq->pTarget = pTarget; 1297 pReq->idx Queue = idxQueue;1297 pReq->idxVirtq = idxVirtq; 1298 1298 pReq->cbDataIn = cbDataIn; 1299 1299 pReq->cbDataOut = cbDataOut; … … 1323 1323 */ 1324 1324 Assert(RT_FAILURE_NP(rc)); 1325 Log2Func(("Request 1325 Log2Func(("Request-submission error from lower-level driver\n")); 1326 1326 uint8_t uASC, uASCQ = 0; 1327 1327 switch (rc) … … 1342 1342 respHdr.uResponse = VIRTIOSCSI_S_FAILURE; 1343 1343 respHdr.uResidual = (cbDataIn + cbDataOut) & UINT32_MAX; 1344 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, idx Queue, pDescChain, &respHdr, abSense, cbSenseCfg);1344 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, idxVirtq, pDescChain, &respHdr, abSense, cbSenseCfg); 1345 1345 virtioScsiR3FreeReq(pTarget, pReq); 1346 1346 } … … 1356 1356 * @param pThis VirtIO SCSI shared instance data. 1357 1357 * @param pThisCC VirtIO SCSI ring-3 instance data. 1358 * @param idx QueueCONTROLQ_IDX1358 * @param idxVirtq CONTROLQ_IDX 1359 1359 * @param pDescChain Descriptor chain to process. 1360 1360 */ 1361 1361 static int virtioScsiR3Ctrl(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, 1362 uint16_t idx Queue, PVIRTIO_DESC_CHAIN_T pDescChain)1362 uint16_t idxVirtq, PVIRTIO_DESC_CHAIN_T pDescChain) 1363 1363 { 1364 1364 AssertReturn(pDescChain->cbPhysSend >= RT_MIN(sizeof(VIRTIOSCSI_CTRL_AN_T), … … 1401 1401 uint32_t uScsiLun = RT_MAKE_U16(ScsiCtrlUnion.Tmf.abScsiLun[3], ScsiCtrlUnion.Tmf.abScsiLun[2]) & 0x3fff; 1402 1402 Log2Func(("[%s] (Target: %d LUN: %d) Task Mgt Function: %s\n", 1403 VIRTQNAME(idx Queue), uTarget, uScsiLun, virtioGetTMFTypeText(ScsiCtrlUnion.Tmf.uSubtype)));1403 VIRTQNAME(idxVirtq), uTarget, uScsiLun, virtioGetTMFTypeText(ScsiCtrlUnion.Tmf.uSubtype))); 1404 1404 1405 1405 if (uTarget >= pThis->cTargets || !pThisCC->paTargetInstances[uTarget].fPresent) … … 1462 1462 virtioGetControlAsyncMaskText(szTypeText, sizeof(szTypeText), ScsiCtrlUnion.AsyncNotify.fEventsRequested); 1463 1463 Log2Func(("[%s] (Target: %d LUN: %d) Async. Notification Query: %s\n", 1464 VIRTQNAME(idx Queue), uTarget, uScsiLun, szTypeText));1464 VIRTQNAME(idxVirtq), uTarget, uScsiLun, szTypeText)); 1465 1465 } 1466 1466 #endif … … 1487 1487 virtioGetControlAsyncMaskText(szTypeText, sizeof(szTypeText), ScsiCtrlUnion.AsyncNotify.fEventsRequested); 1488 1488 Log2Func(("[%s] (Target: %d LUN: %d) Async. Notification Subscribe: %s\n", 1489 VIRTQNAME(idx Queue), uTarget, uScsiLun, szTypeText));1489 VIRTQNAME(idxVirtq), uTarget, uScsiLun, szTypeText)); 1490 1490 } 1491 1491 #endif … … 1508 1508 default: 1509 1509 { 1510 LogFunc(("Unknown control type extracted from %s: %u\n", VIRTQNAME(idx Queue), ScsiCtrlUnion.Type.uType));1510 LogFunc(("Unknown control type extracted from %s: %u\n", VIRTQNAME(idxVirtq), ScsiCtrlUnion.Type.uType)); 1511 1511 1512 1512 bResponse = VIRTIOSCSI_S_FAILURE; … … 1527 1527 RTSgBufInit(&ReqSgBuf, aReqSegs, cSegs); 1528 1528 1529 virtioCoreR3 QueuePut(pDevIns, &pThis->Virtio, idxQueue, &ReqSgBuf, pDescChain, true /*fFence*/);1530 virtioCore QueueSync(pDevIns, &pThis->Virtio, idxQueue);1529 virtioCoreR3VirtqPut(pDevIns, &pThis->Virtio, idxVirtq, &ReqSgBuf, pDescChain, true /*fFence*/); 1530 virtioCoreVirtqSync(pDevIns, &pThis->Virtio, idxVirtq); 1531 1531 1532 1532 return VINF_SUCCESS; … … 1547 1547 static DECLCALLBACK(int) virtioScsiR3WorkerThread(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 1548 1548 { 1549 uint16_t const idx Queue= (uint16_t)(uintptr_t)pThread->pvUser;1549 uint16_t const idxVirtq = (uint16_t)(uintptr_t)pThread->pvUser; 1550 1550 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 1551 1551 PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC); 1552 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[idx Queue];1553 PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[idx Queue];1552 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[idxVirtq]; 1553 PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[idxVirtq]; 1554 1554 1555 1555 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) … … 1558 1558 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 1559 1559 { 1560 if (!pWorkerR3->cRedoDescs && IS_VIRTQ_EMPTY(pDevIns, &pThis->Virtio, idx Queue))1560 if (!pWorkerR3->cRedoDescs && IS_VIRTQ_EMPTY(pDevIns, &pThis->Virtio, idxVirtq)) 1561 1561 { 1562 1562 /* Atomic interlocks avoid missing alarm while going to sleep & notifier waking the awoken */ … … 1565 1565 if (!fNotificationSent) 1566 1566 { 1567 Log6Func(("%s worker sleeping...\n", VIRTQNAME(idx Queue)));1567 Log6Func(("%s worker sleeping...\n", VIRTQNAME(idxVirtq))); 1568 1568 Assert(ASMAtomicReadBool(&pWorker->fSleeping)); 1569 1569 int rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pWorker->hEvtProcess, RT_INDEFINITE_WAIT); … … 1573 1573 if (rc == VERR_INTERRUPTED) 1574 1574 continue; 1575 Log6Func(("%s worker woken\n", VIRTQNAME(idx Queue)));1575 Log6Func(("%s worker woken\n", VIRTQNAME(idxVirtq))); 1576 1576 ASMAtomicWriteBool(&pWorker->fNotified, false); 1577 1577 } … … 1579 1579 } 1580 1580 1581 if (!pThis->af QueueAttached[idxQueue])1581 if (!pThis->afVirtqAttached[idxVirtq]) 1582 1582 { 1583 LogFunc(("%s queue not attached, worker aborting...\n", VIRTQNAME(idx Queue)));1583 LogFunc(("%s queue not attached, worker aborting...\n", VIRTQNAME(idxVirtq))); 1584 1584 break; 1585 1585 } … … 1590 1590 { 1591 1591 PVIRTIO_DESC_CHAIN_T pDescChain; 1592 int rc = virtioCoreR3DescChainGet(pDevIns, &pThis->Virtio, idx Queue,1592 int rc = virtioCoreR3DescChainGet(pDevIns, &pThis->Virtio, idxVirtq, 1593 1593 pWorkerR3->auRedoDescs[i], &pDescChain); 1594 1594 if (RT_FAILURE(rc)) 1595 1595 LogRel(("Error fetching desc chain to redo, %Rrc", rc)); 1596 1596 1597 rc = virtioScsiR3ReqSubmit(pDevIns, pThis, pThisCC, idx Queue, pDescChain);1597 rc = virtioScsiR3ReqSubmit(pDevIns, pThis, pThisCC, idxVirtq, pDescChain); 1598 1598 if (RT_FAILURE(rc)) 1599 1599 LogRel(("Error submitting req packet, resetting %Rrc", rc)); … … 1603 1603 pWorkerR3->cRedoDescs = 0; 1604 1604 1605 Log6Func(("fetching next descriptor chain from %s\n", VIRTQNAME(idx Queue)));1605 Log6Func(("fetching next descriptor chain from %s\n", VIRTQNAME(idxVirtq))); 1606 1606 PVIRTIO_DESC_CHAIN_T pDescChain = NULL; 1607 int rc = virtioCoreR3 QueueGet(pDevIns, &pThis->Virtio, idxQueue, &pDescChain, true);1607 int rc = virtioCoreR3VirtqGet(pDevIns, &pThis->Virtio, idxVirtq, &pDescChain, true); 1608 1608 if (rc == VERR_NOT_AVAILABLE) 1609 1609 { 1610 Log6Func(("Nothing found in %s\n", VIRTQNAME(idx Queue)));1610 Log6Func(("Nothing found in %s\n", VIRTQNAME(idxVirtq))); 1611 1611 continue; 1612 1612 } 1613 1613 1614 1614 AssertRC(rc); 1615 if (idx Queue== CONTROLQ_IDX)1616 virtioScsiR3Ctrl(pDevIns, pThis, pThisCC, idx Queue, pDescChain);1615 if (idxVirtq == CONTROLQ_IDX) 1616 virtioScsiR3Ctrl(pDevIns, pThis, pThisCC, idxVirtq, pDescChain); 1617 1617 else /* request queue index */ 1618 1618 { 1619 rc = virtioScsiR3ReqSubmit(pDevIns, pThis, pThisCC, idx Queue, pDescChain);1619 rc = virtioScsiR3ReqSubmit(pDevIns, pThis, pThisCC, idxVirtq, pDescChain); 1620 1620 if (RT_FAILURE(rc)) 1621 1621 LogRel(("Error submitting req packet, resetting %Rrc", rc)); … … 1703 1703 pThisCC->fQuiescing = false; 1704 1704 1705 for (unsigned i = 0; i < VIRTIOSCSI_ QUEUE_CNT; i++)1706 pThis->af QueueAttached[i] = true;1705 for (unsigned i = 0; i < VIRTIOSCSI_VIRTQ_CNT; i++) 1706 pThis->afVirtqAttached[i] = true; 1707 1707 } 1708 1708 else 1709 1709 { 1710 1710 LogFunc(("VirtIO is resetting\n")); 1711 for (unsigned i = 0; i < VIRTIOSCSI_ QUEUE_CNT; i++)1712 pThis->af QueueAttached[i] = false;1711 for (unsigned i = 0; i < VIRTIOSCSI_VIRTQ_CNT; i++) 1712 pThis->afVirtqAttached[i] = false; 1713 1713 } 1714 1714 } … … 1835 1835 AssertReturn(pv && cb <= sizeof(uint32_t), fWrite ? VINF_SUCCESS : VINF_IOM_MMIO_UNUSED_00); 1836 1836 1837 if (MATCH_SCSI_CONFIG(uNum Queues))1838 SCSI_CONFIG_ACCESSOR_READONLY(uNum Queues);1837 if (MATCH_SCSI_CONFIG(uNumVirtqs)) 1838 SCSI_CONFIG_ACCESSOR_READONLY(uNumVirtqs); 1839 1839 else 1840 1840 if (MATCH_SCSI_CONFIG(uSegMax)) … … 1967 1967 1968 1968 virtioScsiSetVirtqNames(pThis); 1969 for (int idx Queue = 0; idxQueue < VIRTIOSCSI_QUEUE_CNT; idxQueue++)1970 pHlp->pfnSSMGetBool(pSSM, &pThis->af QueueAttached[idxQueue]);1971 1972 pHlp->pfnSSMGetU32(pSSM, &pThis->virtioScsiConfig.uNum Queues);1969 for (int idxVirtq = 0; idxVirtq < VIRTIOSCSI_VIRTQ_CNT; idxVirtq++) 1970 pHlp->pfnSSMGetBool(pSSM, &pThis->afVirtqAttached[idxVirtq]); 1971 1972 pHlp->pfnSSMGetU32(pSSM, &pThis->virtioScsiConfig.uNumVirtqs); 1973 1973 pHlp->pfnSSMGetU32(pSSM, &pThis->virtioScsiConfig.uSegMax); 1974 1974 pHlp->pfnSSMGetU32(pSSM, &pThis->virtioScsiConfig.uMaxSectors); … … 2007 2007 cReqsRedo, VIRTQ_MAX_ENTRIES)); 2008 2008 2009 for (uint16_t idx Queue = VIRTQ_REQ_BASE; idxQueue < VIRTIOSCSI_QUEUE_CNT; idxQueue++)2009 for (uint16_t idxVirtq = VIRTQ_REQ_BASE; idxVirtq < VIRTIOSCSI_VIRTQ_CNT; idxVirtq++) 2010 2010 { 2011 PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[idx Queue];2011 PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[idxVirtq]; 2012 2012 pWorkerR3->cRedoDescs = 0; 2013 2013 } … … 2015 2015 for (int i = 0; i < cReqsRedo; i++) 2016 2016 { 2017 uint16_t idx Queue;2018 rc = pHlp->pfnSSMGetU16(pSSM, &idx Queue);2017 uint16_t idxVirtq; 2018 rc = pHlp->pfnSSMGetU16(pSSM, &idxVirtq); 2019 2019 AssertRCReturn(rc, rc); 2020 AssertReturn(idx Queue < VIRTIOSCSI_QUEUE_CNT,2020 AssertReturn(idxVirtq < VIRTIOSCSI_VIRTQ_CNT, 2021 2021 pHlp->pfnSSMSetLoadError(pSSM, VERR_SSM_DATA_UNIT_FORMAT_CHANGED, RT_SRC_POS, 2022 2022 N_("Bad queue index for re-do in saved state (%#x, max %#x)"), 2023 idx Queue, VIRTIOSCSI_QUEUE_CNT - 1));2023 idxVirtq, VIRTIOSCSI_VIRTQ_CNT - 1)); 2024 2024 2025 2025 uint16_t idxHead; … … 2031 2031 idxHead, VIRTQ_MAX_ENTRIES - 1)); 2032 2032 2033 PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[idx Queue];2033 PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[idxVirtq]; 2034 2034 pWorkerR3->auRedoDescs[pWorkerR3->cRedoDescs++] = idxHead; 2035 2035 pWorkerR3->cRedoDescs %= VIRTQ_MAX_ENTRIES; … … 2045 2045 * Nudge request queue workers 2046 2046 */ 2047 for (int idx Queue = VIRTQ_REQ_BASE; idxQueue < VIRTIOSCSI_QUEUE_CNT; idxQueue++)2048 { 2049 if (pThis->af QueueAttached[idxQueue])2047 for (int idxVirtq = VIRTQ_REQ_BASE; idxVirtq < VIRTIOSCSI_VIRTQ_CNT; idxVirtq++) 2048 { 2049 if (pThis->afVirtqAttached[idxVirtq]) 2050 2050 { 2051 LogFunc(("Waking %s worker.\n", VIRTQNAME(idx Queue)));2052 int rc2 = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->aWorkers[idx Queue].hEvtProcess);2051 LogFunc(("Waking %s worker.\n", VIRTQNAME(idxVirtq))); 2052 int rc2 = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->aWorkers[idxVirtq].hEvtProcess); 2053 2053 AssertRCReturn(rc, rc2); 2054 2054 } … … 2069 2069 LogFunc(("SAVE EXEC!!\n")); 2070 2070 2071 for (int idx Queue = 0; idxQueue < VIRTIOSCSI_QUEUE_CNT; idxQueue++)2072 pHlp->pfnSSMPutBool(pSSM, pThis->af QueueAttached[idxQueue]);2073 2074 pHlp->pfnSSMPutU32(pSSM, pThis->virtioScsiConfig.uNum Queues);2071 for (int idxVirtq = 0; idxVirtq < VIRTIOSCSI_VIRTQ_CNT; idxVirtq++) 2072 pHlp->pfnSSMPutBool(pSSM, pThis->afVirtqAttached[idxVirtq]); 2073 2074 pHlp->pfnSSMPutU32(pSSM, pThis->virtioScsiConfig.uNumVirtqs); 2075 2075 pHlp->pfnSSMPutU32(pSSM, pThis->virtioScsiConfig.uSegMax); 2076 2076 pHlp->pfnSSMPutU32(pSSM, pThis->virtioScsiConfig.uMaxSectors); … … 2117 2117 while(--cReqsRedo) 2118 2118 { 2119 pHlp->pfnSSMPutU16(pSSM, pReq->idx Queue);2119 pHlp->pfnSSMPutU16(pSSM, pReq->idxVirtq); 2120 2120 pHlp->pfnSSMPutU16(pSSM, pReq->pDescChain->uHeadIdx); 2121 2121 … … 2335 2335 * be awake due to new reqs coming in. 2336 2336 */ 2337 for (uint16_t idx Queue = 0; idxQueue < VIRTIOSCSI_REQ_QUEUE_CNT; idxQueue++)2338 { 2339 if (ASMAtomicReadBool(&pThis->aWorkers[idx Queue].fSleeping))2337 for (uint16_t idxVirtq = 0; idxVirtq < VIRTIOSCSI_REQ_VIRTQ_CNT; idxVirtq++) 2338 { 2339 if (ASMAtomicReadBool(&pThis->aWorkers[idxVirtq].fSleeping)) 2340 2340 { 2341 Log6Func(("waking %s worker.\n", VIRTQNAME(idx Queue)));2342 int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->aWorkers[idx Queue].hEvtProcess);2341 Log6Func(("waking %s worker.\n", VIRTQNAME(idxVirtq))); 2342 int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->aWorkers[idxVirtq].hEvtProcess); 2343 2343 AssertRC(rc); 2344 2344 } … … 2414 2414 pThisCC->pMediaNotify = NULL; 2415 2415 2416 for (unsigned idx Queue = 0; idxQueue < VIRTIOSCSI_QUEUE_CNT; idxQueue++)2417 { 2418 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[idx Queue];2416 for (unsigned idxVirtq = 0; idxVirtq < VIRTIOSCSI_VIRTQ_CNT; idxVirtq++) 2417 { 2418 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[idxVirtq]; 2419 2419 if (pWorker->hEvtProcess != NIL_SUPSEMEVENT) 2420 2420 { … … 2423 2423 } 2424 2424 2425 if (pThisCC->aWorkers[idx Queue].pThread)2425 if (pThisCC->aWorkers[idxVirtq].pThread) 2426 2426 { 2427 2427 /* Destroy the thread. */ 2428 2428 int rcThread; 2429 int rc = PDMDevHlpThreadDestroy(pDevIns, pThisCC->aWorkers[idx Queue].pThread, &rcThread);2429 int rc = PDMDevHlpThreadDestroy(pDevIns, pThisCC->aWorkers[idxVirtq].pThread, &rcThread); 2430 2430 if (RT_FAILURE(rc) || RT_FAILURE(rcThread)) 2431 2431 AssertMsgFailed(("%s Failed to destroythread rc=%Rrc rcThread=%Rrc\n", 2432 2432 __FUNCTION__, rc, rcThread)); 2433 pThisCC->aWorkers[idx Queue].pThread = NULL;2433 pThisCC->aWorkers[idxVirtq].pThread = NULL; 2434 2434 } 2435 2435 } … … 2487 2487 2488 2488 /* Configure virtio_scsi_config that transacts via VirtIO implementation's Dev. Specific Cap callbacks */ 2489 pThis->virtioScsiConfig.uNum Queues = VIRTIOSCSI_REQ_QUEUE_CNT;2489 pThis->virtioScsiConfig.uNumVirtqs = VIRTIOSCSI_REQ_VIRTQ_CNT; 2490 2490 pThis->virtioScsiConfig.uSegMax = VIRTIOSCSI_MAX_SEG_COUNT; 2491 2491 pThis->virtioScsiConfig.uMaxSectors = VIRTIOSCSI_MAX_SECTORS_HINT; … … 2499 2499 2500 2500 /* Initialize the generic Virtio core: */ 2501 pThisCC->Virtio.pfn QueueNotified = virtioScsiNotified;2501 pThisCC->Virtio.pfnVirtqNotified = virtioScsiNotified; 2502 2502 pThisCC->Virtio.pfnStatusChanged = virtioScsiR3StatusChanged; 2503 2503 pThisCC->Virtio.pfnDevCapRead = virtioScsiR3DevCapRead; … … 2526 2526 2527 2527 /* Attach the queues and create worker threads for them: */ 2528 for (uint16_t idx Queue = 0; idxQueue < VIRTIOSCSI_QUEUE_CNT; idxQueue++)2529 { 2530 rc = virtioCoreR3 QueueAttach(&pThis->Virtio, idxQueue, VIRTQNAME(idxQueue));2528 for (uint16_t idxVirtq = 0; idxVirtq < VIRTIOSCSI_VIRTQ_CNT; idxVirtq++) 2529 { 2530 rc = virtioCoreR3VirtqAttach(&pThis->Virtio, idxVirtq, VIRTQNAME(idxVirtq)); 2531 2531 if (RT_FAILURE(rc)) 2532 2532 continue; 2533 if (idx Queue == CONTROLQ_IDX || IS_REQ_QUEUE(idxQueue))2533 if (idxVirtq == CONTROLQ_IDX || IS_REQ_VIRTQ(idxVirtq)) 2534 2534 { 2535 rc = PDMDevHlpThreadCreate(pDevIns, &pThisCC->aWorkers[idx Queue].pThread,2536 (void *)(uintptr_t)idx Queue, virtioScsiR3WorkerThread,2537 virtioScsiR3WorkerWakeUp, 0, RTTHREADTYPE_IO, VIRTQNAME(idx Queue));2535 rc = PDMDevHlpThreadCreate(pDevIns, &pThisCC->aWorkers[idxVirtq].pThread, 2536 (void *)(uintptr_t)idxVirtq, virtioScsiR3WorkerThread, 2537 virtioScsiR3WorkerWakeUp, 0, RTTHREADTYPE_IO, VIRTQNAME(idxVirtq)); 2538 2538 if (rc != VINF_SUCCESS) 2539 2539 { 2540 LogRel(("Error creating thread for Virtual Queue %s: %Rrc\n", VIRTQNAME(idxQueue), rc));2540 LogRel(("Error creating thread for Virtual Virtq %s: %Rrc\n", VIRTQNAME(idxVirtq), rc)); 2541 2541 return rc; 2542 2542 } 2543 2543 2544 rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pThis->aWorkers[idx Queue].hEvtProcess);2544 rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pThis->aWorkers[idxVirtq].hEvtProcess); 2545 2545 if (RT_FAILURE(rc)) 2546 2546 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, 2547 2547 N_("DevVirtioSCSI: Failed to create SUP event semaphore")); 2548 2548 } 2549 pThis->af QueueAttached[idxQueue] = true;2549 pThis->afVirtqAttached[idxVirtq] = true; 2550 2550 } 2551 2551 … … 2666 2666 2667 2667 2668 pThisCC->Virtio.pfn QueueNotified = virtioScsiNotified;2668 pThisCC->Virtio.pfnVirtqNotified = virtioScsiNotified; 2669 2669 return virtioCoreRZInit(pDevIns, &pThis->Virtio); 2670 2670 }
Note:
See TracChangeset
for help on using the changeset viewer.