Changeset 83568 in vbox
- Timestamp:
- Apr 5, 2020 8:01:11 PM (4 years ago)
- File:
-
- 1 edited
-
trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp
r83567 r83568 814 814 } 815 815 816 817 /** 818 * Variant of virtioScsiR3ReqErr that takes four (4) REQ_RESP_HDR_T member 819 * fields rather than a pointer to an initialized structure. 820 * 821 * @param pDevIns The device instance. 822 * @param pThis VirtIO SCSI shared instance data. 823 * @param pThisCC VirtIO SCSI ring-3 instance data. 824 * @param qIdx Queue index 825 * @param pDescChain Pointer to pre-processed descriptor chain pulled from virtq 826 * @param pRespHdr Response header 827 * @param cbResidual The number of residual bytes or something like that. 828 * @param bStatus The SCSI status code. 829 * @param bResponse The virtio SCSI response code. 830 * @param pbSense Pointer to sense buffer or NULL if none. 831 * @param cbSense The number of bytes of sense data. Zero if none. 832 * @param cbSenseCfg The configured sense buffer size. 833 * 834 * @returns VINF_SUCCESS 835 */ 836 static int virtioScsiR3ReqErr4(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, uint16_t qIdx, 837 PVIRTIO_DESC_CHAIN_T pDescChain, uint32_t cbResidual, uint8_t bStatus, uint8_t bResponse, 838 uint8_t *pbSense, uint32_t cbSense, uint32_t cbSenseCfg) 839 { 840 REQ_RESP_HDR_T RespHdr; 841 RespHdr.cbSenseLen = cbSense; 842 RespHdr.uResidual = cbResidual; 843 RespHdr.uStatusQualifier = 0; 844 RespHdr.uStatus = bStatus; 845 RespHdr.uResponse = bResponse; 846 847 return virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &RespHdr, pbSense, cbSenseCfg); 848 } 849 816 850 static void virtioScsiR3SenseKeyToVirtioResp(REQ_RESP_HDR_T *respHdr, uint8_t uSenseKey) 817 851 { … … 1098 1132 * Validate configuration values we use here before we start. 1099 1133 */ 1134 uint32_t const cbCdb = pThis->virtioScsiConfig.uCdbSize; 1135 uint32_t const cbSenseCfg = pThis->virtioScsiConfig.uSenseSize; 1100 1136 /** @todo Report these as errors to the guest or does the caller do that? */ 1101 uint32_t const cbCdb = pThis->virtioScsiConfig.uCdbSize;1102 1137 ASSERT_GUEST_LOGREL_MSG_RETURN(cbCdb <= VIRTIOSCSI_CDB_SIZE_MAX, ("cbCdb=%#x\n", cbCdb), VERR_OUT_OF_RANGE); 1103 uint32_t const cbSense = pThis->virtioScsiConfig.uSenseSize; 1104 ASSERT_GUEST_LOGREL_MSG_RETURN(cbSense <= VIRTIOSCSI_SENSE_SIZE_MAX, ("cbSense=%#x\n", cbSense), VERR_OUT_OF_RANGE); 1138 ASSERT_GUEST_LOGREL_MSG_RETURN(cbSenseCfg <= VIRTIOSCSI_SENSE_SIZE_MAX, ("cbSenseCfg=%#x\n", cbSenseCfg), VERR_OUT_OF_RANGE); 1105 1139 1106 1140 /* … … 1164 1198 */ 1165 1199 uint32_t const offDataOut = sizeof(REQ_CMD_HDR_T) + cbCdb; 1166 uint32_t const offDataIn = sizeof(REQ_RESP_HDR_T) + cbSense ;1200 uint32_t const offDataIn = sizeof(REQ_RESP_HDR_T) + cbSenseCfg; 1167 1201 uint32_t const cbDataOut = pDescChain->cbPhysSend - offDataOut; 1168 1202 /** @todo r=bird: Validate cbPhysReturn properly? I've just RT_MAX'ed it for now. */ … … 1179 1213 { 1180 1214 Log2Func(("Error submitting request, bad LUN format\n")); 1181 REQ_RESP_HDR_T respHdr = { 0 }; 1182 respHdr.cbSenseLen = 0; 1183 respHdr.uStatus = 0; 1184 respHdr.uResponse = VIRTIOSCSI_S_FAILURE; 1185 respHdr.uResidual = cbDataIn + cbDataOut; 1186 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, NULL, cbSense); 1187 return VINF_SUCCESS; 1188 } 1189 1215 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, qIdx, pDescChain, cbDataIn + cbDataOut, 0 /*bStatus*/, 1216 VIRTIOSCSI_S_FAILURE, NULL /*pbSense*/, 0 /*cbSense*/, cbSenseCfg); 1217 } 1218 1219 PVIRTIOSCSITARGET const pTarget = &pThisCC->paTargetInstances[uTarget]; 1190 1220 if (RT_LIKELY( uTarget < pThis->cTargets 1191 && pT hisCC->paTargetInstances[uTarget].fPresent1192 && pT hisCC->paTargetInstances[uTarget].pDrvMediaEx))1221 && pTarget->fPresent 1222 && pTarget->pDrvMediaEx)) 1193 1223 { /* likely */ } 1194 1224 else … … 1198 1228 0, SCSI_SENSE_ILLEGAL_REQUEST, 1199 1229 0, 0, 0, 0, 10, SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED, 0, 0 }; 1200 REQ_RESP_HDR_T respHdr = { 0 }; 1201 respHdr.cbSenseLen = sizeof(abSense); 1202 respHdr.uStatus = SCSI_STATUS_CHECK_CONDITION; 1203 respHdr.uResponse = VIRTIOSCSI_S_BAD_TARGET; 1204 respHdr.uResidual = cbDataOut + cbDataIn; 1205 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense, cbSense); 1206 return VINF_SUCCESS; 1207 1230 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, qIdx, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_CHECK_CONDITION, 1231 VIRTIOSCSI_S_BAD_TARGET, abSense, sizeof(abSense), cbSenseCfg); 1208 1232 } 1209 1233 if (RT_LIKELY(uScsiLun == 0)) … … 1215 1239 0, SCSI_SENSE_ILLEGAL_REQUEST, 1216 1240 0, 0, 0, 0, 10, SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED, 0, 0 }; 1217 REQ_RESP_HDR_T respHdr = { 0 }; 1218 respHdr.cbSenseLen = sizeof(abSense); 1219 respHdr.uStatus = SCSI_STATUS_CHECK_CONDITION; 1220 respHdr.uResponse = VIRTIOSCSI_S_OK; 1221 respHdr.uResidual = cbDataOut + cbDataIn; 1222 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense, cbSense); 1223 return VINF_SUCCESS; 1241 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, qIdx, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_CHECK_CONDITION, 1242 VIRTIOSCSI_S_OK, abSense, sizeof(abSense), cbSenseCfg); 1224 1243 } 1225 1244 if (RT_LIKELY(!pThis->fResetting)) … … 1228 1247 { 1229 1248 Log2Func(("Aborting req submission because reset is in progress\n")); 1230 REQ_RESP_HDR_T respHdr = { 0 }; 1231 respHdr.cbSenseLen = 0; 1232 respHdr.uStatus = SCSI_STATUS_OK; 1233 respHdr.uResponse = VIRTIOSCSI_S_RESET; 1234 respHdr.uResidual = cbDataIn + cbDataOut; 1235 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, NULL, cbSense); 1236 return VINF_SUCCESS; 1237 } 1238 1239 PVIRTIOSCSITARGET pTarget = &pThisCC->paTargetInstances[uTarget]; 1249 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, qIdx, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_OK, 1250 VIRTIOSCSI_S_RESET, NULL /*pbSense*/, 0 /*cbSense*/, cbSenseCfg); 1251 } 1240 1252 1241 1253 if (RT_LIKELY(!cbDataIn || !cbDataOut || pThis->fHasInOutBufs)) /* VirtIO 1.0, 5.6.6.1.1 */ … … 1246 1258 uint8_t abSense[] = { RT_BIT(7) | SCSI_SENSE_RESPONSE_CODE_CURR_FIXED, 1247 1259 0, SCSI_SENSE_ILLEGAL_REQUEST, 0, 0, 0, 0, 10, 0, 0, 0 }; 1248 REQ_RESP_HDR_T respHdr = { 0 }; 1249 respHdr.cbSenseLen = sizeof(abSense); 1250 respHdr.uStatus = SCSI_STATUS_CHECK_CONDITION; 1251 respHdr.uResponse = VIRTIOSCSI_S_FAILURE; 1252 respHdr.uResidual = cbDataIn + cbDataOut; 1253 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense, cbSense); 1254 return VINF_SUCCESS; 1260 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, qIdx, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_CHECK_CONDITION, 1261 VIRTIOSCSI_S_FAILURE, abSense, sizeof(abSense), cbSenseCfg); 1255 1262 } 1256 1263 … … 1258 1265 * Have underlying driver allocate a req of size set during initialization of this device. 1259 1266 */ 1260 PDMMEDIAEXIOREQ hIoReq= NULL;1261 PVIRTIOSCSIREQ pReq;1262 PPDMIMEDIAEX pIMediaEx = pTarget->pDrvMediaEx;1267 PDMMEDIAEXIOREQ hIoReq = NULL; 1268 PVIRTIOSCSIREQ pReq = NULL; 1269 PPDMIMEDIAEX pIMediaEx = pTarget->pDrvMediaEx; 1263 1270 1264 1271 int rc = pIMediaEx->pfnIoReqAlloc(pIMediaEx, &hIoReq, (void **)&pReq, 0 /* uIoReqId */, … … 1276 1283 pReq->uDataOutOff = offDataOut; 1277 1284 1278 pReq->cbSenseAlloc = cbSense ;1285 pReq->cbSenseAlloc = cbSenseCfg; 1279 1286 pReq->pbSense = (uint8_t *)RTMemAllocZ(pReq->cbSenseAlloc); 1280 1287 AssertMsgReturnStmt(pReq->pbSense, ("Out of memory allocating sense buffer"), … … 1315 1322 respHdr.uResponse = VIRTIOSCSI_S_FAILURE; 1316 1323 respHdr.uResidual = cbDataIn + cbDataOut; 1317 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense, cbSense );1324 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense, cbSenseCfg); 1318 1325 virtioScsiR3FreeReq(pTarget, pReq); 1319 1326 }
Note:
See TracChangeset
for help on using the changeset viewer.

