Changeset 80521 in vbox
- Timestamp:
- Aug 31, 2019 1:35:35 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp
r80501 r80521 21 21 * Header Files * 22 22 *********************************************************************************************************************************/ 23 #define LOG_GROUP LOG_GROUP_DRV_SCSI 23 //#define LOG_GROUP LOG_GROUP_DRV_SCSI 24 #define LOG_GROUP LOG_GROUP_DEV_VIRTIO 24 25 25 26 #include <VBox/vmm/pdmdev.h> … … 56 57 /** @} */ 57 58 58 #define VIRTIOSCSI_HOST_SCSI_ALL_FEATURES \ 59 60 #define VIRTIOSCSI_HOST_SCSI_FEATURES_ALL \ 59 61 (VIRTIO_SCSI_F_INOUT | VIRTIO_SCSI_F_HOTPLUG | VIRTIO_SCSI_F_CHANGE | VIRTIO_SCSI_F_T10_PI) 60 62 61 #define VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED 0 /**< TBD, support at least hotplug & in/out */ 63 #define VIRTIOSCSI_HOST_SCSI_FEATURES_NONE 0 64 65 #define VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED \ 66 VIRTIOSCSI_HOST_SCSI_FEATURES_NONE 62 67 63 68 /** … … 66 71 #define VIRTIOSCSI_REQ_QUEUE_CNT 1 /**< Number of req queues exposed by dev. */ 67 72 #define VIRTIOSCSI_QUEUE_CNT VIRTIOSCSI_REQ_QUEUE_CNT + 2 68 #define VIRTIOSCSI_MAX_TARGETS 1 /**< Can probably determined from higher layers 69 #define VIRTIOSCSI_MAX_LUN 1 6383/* < VirtIO specification, section 5.6.4 */73 #define VIRTIOSCSI_MAX_TARGETS 1 /**< Can probably determined from higher layers */ 74 #define VIRTIOSCSI_MAX_LUN 1 /* < VirtIO specification, section 5.6.4 */ 70 75 #define VIRTIOSCSI_MAX_COMMANDS_PER_LUN 1 /* < T.B.D. What is a good value for this? */ 71 76 #define VIRTIOSCSI_MAX_SEG_COUNT 1024 /* < T.B.D. What is a good value for this? */ 72 77 #define VIRTIOSCSI_MAX_SECTORS_HINT 0x10000 /* < VirtIO specification, section 5.6.4 */ 73 #define VIRTIOSCSI_MAX_CHANNEL_HINT 0 /* < VirtIO specification, section 5.6.4 78 #define VIRTIOSCSI_MAX_CHANNEL_HINT 0 /* < VirtIO specification, section 5.6.4 should be 0 */ 74 79 #define VIRTIOSCSI_SAVED_STATE_MINOR_VERSION 0x01 /**< SSM version # */ 75 80 … … 80 85 #define VIRTIOSCSI_PCI_CLASS 0x01 /**< Base class Mass Storage? */ 81 86 87 88 #define VIRTIOSCSI_SENSE_SIZE_DEFAULT 96 /**< VirtIO 1.0: 96 on reset, guest can change */ 89 #define VIRTIOSCSI_CDB_SIZE_DEFAULT 32 /**< VirtIO 1.0: 32 on reset, guest can change */ 90 #define VIRTIOSCSI_PI_BYTES_IN 1 /**< Value TBD (see section 5.6.6.1) */ 91 #define VIRTIOSCSI_PI_BYTES_OUT 1 /**< Value TBD (see section 5.6.6.1) */ 92 #define VIRTIOSCSI_DATA_OUT 512 /**< Value TBD (see section 5.6.6.1) */ 93 82 94 /** 83 95 * VirtIO SCSI Host Device device-specific queue indicies … … 91 103 #define VIRTQ_REQ_BASE 2 /**< Spec-defined base index of request queues */ 92 104 93 #define QUEUENAME(qIdx) (pThis->szQueueNames[qIdx]) /**< Macro to get queue name from its index */105 #define QUEUENAME(qIdx) (pThis->szQueueNames[qIdx]) /**< Macro to get queue name from its index */ 94 106 #define CBQUEUENAME(qIdx) RTStrNLen(QUEUENAME(qIdx), sizeof(QUEUENAME(qIdx))) 95 107 … … 144 156 /** @} */ 145 157 158 159 #pragma pack(1) 160 146 161 /** 147 162 * Device operation: reqestq 148 * 149 * The following struct is described in VirtIO 1.0 Specification, section 5.6.6.1 150 */ 151 #define VIRTIOSCSI_SENSE_SIZE_DEFAULT 96 /**< VirtIO 1.0: 96 on reset, guest can change */ 152 #define VIRTIOSCSI_CDB_SIZE_DEFAULT 32 /**< VirtIO 1.0: 32 on reset, guest can change */ 153 #define VIRTIOSCSI_PI_BYTES_IN 1 /**< Value TBD (see section 5.6.6.1) */ 154 #define VIRTIOSCSI_PI_BYTES_OUT 1 /**< Value TBD (see section 5.6.6.1) */ 155 #define VIRTIOSCSI_DATA_OUT 512 /**< Value TBD (see section 5.6.6.1) */ 156 157 #pragma pack(1) 158 163 */ 159 164 struct REQ_CMD_HDR 160 165 { … … 804 809 } 805 810 806 static int virtioScsiScrapReq(PVIRTIOSCSI pThis, uint16_t qIdx, uint32_t rcReq) 811 /** 812 * This is called to complete a request buffer immediately 813 * 814 * @param pThis - PDM driver instance state 815 * @param qIdx - Queue index 816 * @param rcReq - VirtualBox code to map to VirtIO response code. 817 * 818 * @returns virtual box status code 819 */ 820 static int virtioScsiReqComplete(PVIRTIOSCSI pThis, uint16_t qIdx, uint32_t rcReq) 807 821 { 808 822 struct REQ_RESP_HDR respHdr; … … 815 829 RTSGSEG aReqSegs[] = { { &respHdr, sizeof(respHdr) } }; 816 830 RTSgBufInit(&reqSegBuf, aReqSegs, 1); 817 virtioQueuePut(pThis->hVirtio, qIdx, &reqSegBuf, false /* fFence */);831 virtioQueuePut(pThis->hVirtio, qIdx, &reqSegBuf, true /* fFence */); 818 832 virtioQueueSync(pThis->hVirtio, qIdx); 819 833 LogFunc(("Response code: %s\n", virtioGetReqRespText(respHdr.uResponse))); … … 825 839 PVIRTIOSCSITARGET pTarget = pReq->pTarget; 826 840 PPDMIMEDIAEX pIMediaEx = pTarget->pDrvMediaEx; 827 RTSGBUF reqSegBuf; 828 829 Assert(pReq->pbDataIn && pReq->pbSense); 841 830 842 ASMAtomicDecU32(&pTarget->cReqsInProgress); 831 843 … … 833 845 int rc = pIMediaEx->pfnIoReqQueryResidual(pIMediaEx, pReq->hIoReq, &cbResidual); 834 846 AssertRC(rc); Assert(cbResidual == (uint32_t)cbResidual); 847 848 /** 849 * Linux does not want any sense code if there wasn't problem! 850 */ 851 if (pReq->pbSense[2] == SCSI_SENSE_NONE) 852 pReq->cbSense = 0; 835 853 836 854 struct REQ_RESP_HDR respHdr; … … 856 874 LogFunc(("Residual: %d\n", cbResidual)); 857 875 858 if (pReq->pbPiIn) 859 { 860 RTSGSEG aReqSegs[] = { 861 { &respHdr, sizeof(respHdr) }, 862 { pReq->pbSense, pReq->cbSense }, 863 { pReq->pbPiIn, pReq->cbPiIn }, 864 { pReq->pbDataIn, pReq->cbDataIn } 865 }; 866 RTSgBufInit(&reqSegBuf, aReqSegs, sizeof(aReqSegs) / sizeof(RTSGSEG)); 867 } 868 else /** Much easier not to include piIn sgbuf than to account for it during copy! */ 869 { 870 RTSGSEG aReqSegs[] = { 871 { &respHdr, sizeof(respHdr) }, 872 { pReq->pbSense, pReq->cbSense }, 873 { pReq->pbDataIn, pReq->cbDataIn } 874 }; 875 RTSgBufInit(&reqSegBuf, aReqSegs, sizeof(aReqSegs) / sizeof(RTSGSEG)); 876 } 876 int cSegs = 0; 877 RTSGSEG aReqSegs[4]; 878 aReqSegs[cSegs].pvSeg = &respHdr; 879 aReqSegs[cSegs++].cbSeg = sizeof(respHdr); 880 if (pReq->cbSense) 881 { 882 aReqSegs[cSegs].pvSeg = pReq->pbSense; 883 aReqSegs[cSegs++].cbSeg = pReq->cbSense; 884 } 885 if (pReq->cbPiIn) 886 { 887 aReqSegs[cSegs].pvSeg = pReq->pbPiIn; 888 aReqSegs[cSegs++].cbSeg = pReq->cbPiIn; 889 } 890 if (pReq->cbDataIn) 891 { 892 aReqSegs[cSegs].pvSeg = pReq->pbDataIn; 893 aReqSegs[cSegs++].cbSeg = pReq->cbDataIn; 894 } 895 RTSGBUF reqSegBuf; 896 RTSgBufInit(&reqSegBuf, aReqSegs, cSegs); 877 897 878 898 /** … … 890 910 * VirtIO 1.0 Spec requires mem. barrier for ctrl cmds 891 911 * but doesn't mention fences in regard to requests. */ 892 virtioQueuePut(pThis->hVirtio, pReq->qIdx, &reqSegBuf, false /* fFence*/);912 virtioQueuePut(pThis->hVirtio, pReq->qIdx, &reqSegBuf, true /* fFence TBD */); 893 913 virtioQueueSync(pThis->hVirtio, pReq->qIdx); 894 914 … … 963 983 if (uTarget >= pThis->cTargets) 964 984 { 965 virtioScsiScrapReq(pThis, qIdx, VERR_IO_BAD_UNIT); 985 virtioScsiReqComplete(pThis, qIdx, VERR_IO_BAD_UNIT); 986 return VINF_SUCCESS; 987 } 988 if (uLUN != 0) 989 { 990 virtioScsiReqComplete(pThis, qIdx, VERR_IO_BAD_UNIT); 966 991 return VINF_SUCCESS; 967 992 } … … 1023 1048 AssertMsgReturn(pReq->pbPiIn, ("Out of memory allocating pi_in buffer"), VERR_NO_MEMORY); 1024 1049 } 1025 pReq->cbDataIn = cbDataIn; 1026 pReq->pbDataIn = (uint8_t *)RTMemAllocZ(cbDataIn); 1027 AssertMsgReturn(pReq->pbDataIn, ("Out of memory allocating datain buffer"), VERR_NO_MEMORY); 1028 1029 pReq->cbSense = cbSense; 1030 pReq->pbSense = (uint8_t *)RTMemAllocZ(cbSense); 1031 pReq->pInSgBuf = pInSgBuf; 1032 AssertMsgReturn(pReq->pbSense, ("Out of memory allocating sense buffer"), VERR_NO_MEMORY); 1050 1051 if (cbDataIn) 1052 { 1053 pReq->cbDataIn = cbDataIn; 1054 pReq->pbDataIn = (uint8_t *)RTMemAllocZ(cbDataIn); 1055 AssertMsgReturn(pReq->pbDataIn, ("Out of memory allocating datain buffer"), VERR_NO_MEMORY); 1056 } 1057 1058 if (cbSense) 1059 { 1060 pReq->cbSense = cbSense; 1061 pReq->pbSense = (uint8_t *)RTMemAllocZ(cbSense); 1062 pReq->pInSgBuf = pInSgBuf; 1063 AssertMsgReturn(pReq->pbSense, ("Out of memory allocating sense buffer"), VERR_NO_MEMORY); 1064 } 1033 1065 1034 1066 LogFunc(("Submitting req (target=%d, LUN=%x) on %s\n", uTarget, uLUN, QUEUENAME(qIdx))); … … 1040 1072 if (rc != VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS) 1041 1073 { 1042 virtioScsiScrapReq(pThis, qIdx, rc); 1074 pIMediaEx->pfnIoReqFree(pIMediaEx, hIoReq); 1075 virtioScsiReqComplete(pThis, qIdx, rc); 1043 1076 return VINF_SUCCESS; 1044 1077 } 1045 1078 } else { 1046 virtioScsi ScrapReq(pThis, qIdx, VERR_IO_NOT_READY);1079 virtioScsiReqComplete(pThis, qIdx, VERR_IO_NOT_READY); 1047 1080 return VINF_SUCCESS; 1048 1081
Note:
See TracChangeset
for help on using the changeset viewer.