- Timestamp:
- Oct 7, 2010 3:14:54 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 66493
- Location:
- trunk/src/VBox/Devices/Storage
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevBusLogic.cpp
r30809 r32983 2013 2013 } 2014 2014 2015 static DECLCALLBACK(int) buslogicDeviceSCSIRequestCompleted(PPDMISCSIPORT pInterface, PPDMSCSIREQUEST pSCSIRequest, int rcCompletion) 2015 static DECLCALLBACK(int) buslogicDeviceSCSIRequestCompleted(PPDMISCSIPORT pInterface, PPDMSCSIREQUEST pSCSIRequest, 2016 int rcCompletion, bool fRedo, int rcReq) 2016 2017 { 2017 2018 int rc; -
trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
r32938 r32983 103 103 } LSILOGICDEVICE, *PLSILOGICDEVICE; 104 104 105 /** Pointer to a task state. */ 106 typedef struct LSILOGICTASKSTATE *PLSILOGICTASKSTATE; 107 105 108 /** 106 109 * Device instance data for the emulated … … 290 293 * a port is entering the idle state. */ 291 294 bool volatile fSignalIdle; 295 /** Flag whether we have tasks which need to be processed again- */ 296 bool volatile fRedo; 297 /** List of tasks which can be redone. */ 298 R3PTRTYPE(volatile PLSILOGICTASKSTATE) pTasksRedoHead; 292 299 293 300 } LSILOGISCSI, *PLSILOGICSCSI; … … 325 332 typedef struct LSILOGICTASKSTATE 326 333 { 334 /** Next in the redo list. */ 335 PLSILOGICTASKSTATE pRedoNext; 327 336 /** Target device. */ 328 337 PLSILOGICDEVICE pTargetDevice; … … 360 369 /** Flag whether the request was issued from the BIOS. */ 361 370 bool fBIOS; 362 } LSILOGICTASKSTATE , *PLSILOGICTASKSTATE;371 } LSILOGICTASKSTATE; 363 372 364 373 #ifndef VBOX_DEVICE_STRUCT_TESTCASE … … 1893 1902 #endif 1894 1903 1904 static void lsilogicWarningDiskFull(PPDMDEVINS pDevIns) 1905 { 1906 int rc; 1907 LogRel(("LsiLogic#%d: Host disk full\n", pDevIns->iInstance)); 1908 rc = PDMDevHlpVMSetRuntimeError(pDevIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DevLsiLogic_DISKFULL", 1909 N_("Host system reported disk full. VM execution is suspended. You can resume after freeing some space")); 1910 AssertRC(rc); 1911 } 1912 1913 static void lsilogicWarningFileTooBig(PPDMDEVINS pDevIns) 1914 { 1915 int rc; 1916 LogRel(("LsiLogic#%d: File too big\n", pDevIns->iInstance)); 1917 rc = PDMDevHlpVMSetRuntimeError(pDevIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DevLsiLogic_FILETOOBIG", 1918 N_("Host system reported that the file size limit of the host file system has been exceeded. VM execution is suspended. You need to move your virtual hard disk to a filesystem which allows bigger files")); 1919 AssertRC(rc); 1920 } 1921 1922 static void lsilogicWarningISCSI(PPDMDEVINS pDevIns) 1923 { 1924 int rc; 1925 LogRel(("LsiLogic#%d: iSCSI target unavailable\n", pDevIns->iInstance)); 1926 rc = PDMDevHlpVMSetRuntimeError(pDevIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DevLsiLogic_ISCSIDOWN", 1927 N_("The iSCSI target has stopped responding. VM execution is suspended. You can resume when it is available again")); 1928 AssertRC(rc); 1929 } 1930 1931 static void lsilogicWarningUnknown(PPDMDEVINS pDevIns, int rc) 1932 { 1933 int rc2; 1934 LogRel(("LsiLogic#%d: Unknown but recoverable error has occurred (rc=%Rrc)\n", pDevIns->iInstance, rc)); 1935 rc2 = PDMDevHlpVMSetRuntimeError(pDevIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DevLsiLogic_UNKNOWN", 1936 N_("An unknown but recoverable I/O error has occurred (rc=%Rrc). VM execution is suspended. You can resume when the error is fixed"), rc); 1937 AssertRC(rc2); 1938 } 1939 1940 static void lsilogicRedoSetWarning(PLSILOGICSCSI pThis, int rc) 1941 { 1942 if (rc == VERR_DISK_FULL) 1943 lsilogicWarningDiskFull(pThis->CTX_SUFF(pDevIns)); 1944 else if (rc == VERR_FILE_TOO_BIG) 1945 lsilogicWarningFileTooBig(pThis->CTX_SUFF(pDevIns)); 1946 else if (rc == VERR_BROKEN_PIPE || rc == VERR_NET_CONNECTION_REFUSED) 1947 { 1948 /* iSCSI connection abort (first error) or failure to reestablish 1949 * connection (second error). Pause VM. On resume we'll retry. */ 1950 lsilogicWarningISCSI(pThis->CTX_SUFF(pDevIns)); 1951 } 1952 else 1953 lsilogicWarningUnknown(pThis->CTX_SUFF(pDevIns), rc); 1954 } 1955 1895 1956 /** 1896 1957 * Processes a SCSI I/O request by setting up the request … … 2019 2080 } 2020 2081 2021 /** 2022 * Called upon completion of the request from the SCSI driver below. 2023 * This function frees all allocated ressources and notifies the guest 2024 * that the process finished by asserting an interrupt. 2025 * 2026 * @returns VBox status code. 2027 * @param pInterface Pointer to the interface the called funtion belongs to. 2028 * @param pSCSIRequest Pointer to the SCSI request which finished. 2029 */ 2030 static DECLCALLBACK(int) lsilogicDeviceSCSIRequestCompleted(PPDMISCSIPORT pInterface, PPDMSCSIREQUEST pSCSIRequest, int rcCompletion) 2082 2083 static DECLCALLBACK(int) lsilogicDeviceSCSIRequestCompleted(PPDMISCSIPORT pInterface, PPDMSCSIREQUEST pSCSIRequest, 2084 int rcCompletion, bool fRedo, int rcReq) 2031 2085 { 2032 2086 PLSILOGICTASKSTATE pTaskState = (PLSILOGICTASKSTATE)pSCSIRequest->pvUser; … … 2034 2088 PLSILOGICSCSI pLsiLogic = pLsiLogicDevice->CTX_SUFF(pLsiLogic); 2035 2089 2090 /* If the task failed but it is possible to redo it again after a suspend 2091 * add it to the list. */ 2092 if (fRedo) 2093 { 2094 if (!pTaskState->fBIOS) 2095 lsilogicScatterGatherListDestroy(pLsiLogic, pTaskState); 2096 2097 /* Add to the list. */ 2098 do 2099 { 2100 pTaskState->pRedoNext = ASMAtomicReadPtrT(&pLsiLogic->pTasksRedoHead, PLSILOGICTASKSTATE); 2101 } while (!ASMAtomicCmpXchgPtr(&pLsiLogic->pTasksRedoHead, pTaskState, pTaskState->pRedoNext)); 2102 2103 /* Suspend the VM if not done already. */ 2104 if (!ASMAtomicXchgBool(&pLsiLogic->fRedo, true)) 2105 lsilogicRedoSetWarning(pLsiLogic, rcReq); 2106 } 2107 else 2108 { 2109 if (RT_UNLIKELY(pTaskState->fBIOS)) 2110 { 2111 int rc = vboxscsiRequestFinished(&pLsiLogic->VBoxSCSI, pSCSIRequest); 2112 AssertMsgRC(rc, ("Finishing BIOS SCSI request failed rc=%Rrc\n", rc)); 2113 } 2114 else 2115 { 2116 #if 0 2117 lsilogicFreeGCSenseBuffer(pLsiLogic, pTaskState); 2118 #else 2119 RTGCPHYS GCPhysAddrSenseBuffer; 2120 2121 GCPhysAddrSenseBuffer = pTaskState->GuestRequest.SCSIIO.u32SenseBufferLowAddress; 2122 GCPhysAddrSenseBuffer |= ((uint64_t)pLsiLogic->u32SenseBufferHighAddr << 32); 2123 2124 /* Copy the sense buffer over. */ 2125 PDMDevHlpPhysWrite(pLsiLogic->CTX_SUFF(pDevIns), GCPhysAddrSenseBuffer, pTaskState->abSenseBuffer, 2126 RT_UNLIKELY(pTaskState->GuestRequest.SCSIIO.u8SenseBufferLength < pTaskState->PDMScsiRequest.cbSenseBuffer) 2127 ? pTaskState->GuestRequest.SCSIIO.u8SenseBufferLength 2128 : pTaskState->PDMScsiRequest.cbSenseBuffer); 2129 #endif 2130 lsilogicScatterGatherListDestroy(pLsiLogic, pTaskState); 2131 2132 2133 if (RT_LIKELY(rcCompletion == SCSI_STATUS_OK)) 2134 lsilogicFinishContextReply(pLsiLogic, pTaskState->GuestRequest.SCSIIO.u32MessageContext); 2135 else 2136 { 2137 /* The SCSI target encountered an error during processing post a reply. */ 2138 memset(&pTaskState->IOCReply, 0, sizeof(MptReplyUnion)); 2139 pTaskState->IOCReply.SCSIIOError.u8TargetID = pTaskState->GuestRequest.SCSIIO.u8TargetID; 2140 pTaskState->IOCReply.SCSIIOError.u8Bus = pTaskState->GuestRequest.SCSIIO.u8Bus; 2141 pTaskState->IOCReply.SCSIIOError.u8MessageLength = 8; 2142 pTaskState->IOCReply.SCSIIOError.u8Function = pTaskState->GuestRequest.SCSIIO.u8Function; 2143 pTaskState->IOCReply.SCSIIOError.u8CDBLength = pTaskState->GuestRequest.SCSIIO.u8CDBLength; 2144 pTaskState->IOCReply.SCSIIOError.u8SenseBufferLength = pTaskState->GuestRequest.SCSIIO.u8SenseBufferLength; 2145 pTaskState->IOCReply.SCSIIOError.u8MessageFlags = pTaskState->GuestRequest.SCSIIO.u8MessageFlags; 2146 pTaskState->IOCReply.SCSIIOError.u32MessageContext = pTaskState->GuestRequest.SCSIIO.u32MessageContext; 2147 pTaskState->IOCReply.SCSIIOError.u8SCSIStatus = rcCompletion; 2148 pTaskState->IOCReply.SCSIIOError.u8SCSIState = MPT_SCSI_IO_ERROR_SCSI_STATE_AUTOSENSE_VALID; 2149 pTaskState->IOCReply.SCSIIOError.u16IOCStatus = 0; 2150 pTaskState->IOCReply.SCSIIOError.u32IOCLogInfo = 0; 2151 pTaskState->IOCReply.SCSIIOError.u32TransferCount = 0; 2152 pTaskState->IOCReply.SCSIIOError.u32SenseCount = sizeof(pTaskState->abSenseBuffer); 2153 pTaskState->IOCReply.SCSIIOError.u32ResponseInfo = 0; 2154 2155 lsilogicFinishAddressReply(pLsiLogic, &pTaskState->IOCReply, true); 2156 } 2157 } 2158 2159 RTMemCacheFree(pLsiLogic->hTaskCache, pTaskState); 2160 } 2161 2036 2162 ASMAtomicDecU32(&pLsiLogicDevice->cOutstandingRequests); 2037 2038 if (RT_UNLIKELY(pTaskState->fBIOS))2039 {2040 int rc = vboxscsiRequestFinished(&pLsiLogic->VBoxSCSI, pSCSIRequest);2041 AssertMsgRC(rc, ("Finishing BIOS SCSI request failed rc=%Rrc\n", rc));2042 }2043 else2044 {2045 #if 02046 lsilogicFreeGCSenseBuffer(pLsiLogic, pTaskState);2047 #else2048 RTGCPHYS GCPhysAddrSenseBuffer;2049 2050 GCPhysAddrSenseBuffer = pTaskState->GuestRequest.SCSIIO.u32SenseBufferLowAddress;2051 GCPhysAddrSenseBuffer |= ((uint64_t)pLsiLogic->u32SenseBufferHighAddr << 32);2052 2053 /* Copy the sense buffer over. */2054 PDMDevHlpPhysWrite(pLsiLogic->CTX_SUFF(pDevIns), GCPhysAddrSenseBuffer, pTaskState->abSenseBuffer,2055 RT_UNLIKELY(pTaskState->GuestRequest.SCSIIO.u8SenseBufferLength < pTaskState->PDMScsiRequest.cbSenseBuffer)2056 ? pTaskState->GuestRequest.SCSIIO.u8SenseBufferLength2057 : pTaskState->PDMScsiRequest.cbSenseBuffer);2058 #endif2059 lsilogicScatterGatherListDestroy(pLsiLogic, pTaskState);2060 2061 2062 if (RT_LIKELY(rcCompletion == SCSI_STATUS_OK))2063 lsilogicFinishContextReply(pLsiLogic, pTaskState->GuestRequest.SCSIIO.u32MessageContext);2064 else2065 {2066 /* The SCSI target encountered an error during processing post a reply. */2067 memset(&pTaskState->IOCReply, 0, sizeof(MptReplyUnion));2068 pTaskState->IOCReply.SCSIIOError.u8TargetID = pTaskState->GuestRequest.SCSIIO.u8TargetID;2069 pTaskState->IOCReply.SCSIIOError.u8Bus = pTaskState->GuestRequest.SCSIIO.u8Bus;2070 pTaskState->IOCReply.SCSIIOError.u8MessageLength = 8;2071 pTaskState->IOCReply.SCSIIOError.u8Function = pTaskState->GuestRequest.SCSIIO.u8Function;2072 pTaskState->IOCReply.SCSIIOError.u8CDBLength = pTaskState->GuestRequest.SCSIIO.u8CDBLength;2073 pTaskState->IOCReply.SCSIIOError.u8SenseBufferLength = pTaskState->GuestRequest.SCSIIO.u8SenseBufferLength;2074 pTaskState->IOCReply.SCSIIOError.u8MessageFlags = pTaskState->GuestRequest.SCSIIO.u8MessageFlags;2075 pTaskState->IOCReply.SCSIIOError.u32MessageContext = pTaskState->GuestRequest.SCSIIO.u32MessageContext;2076 pTaskState->IOCReply.SCSIIOError.u8SCSIStatus = rcCompletion;2077 pTaskState->IOCReply.SCSIIOError.u8SCSIState = MPT_SCSI_IO_ERROR_SCSI_STATE_AUTOSENSE_VALID;2078 pTaskState->IOCReply.SCSIIOError.u16IOCStatus = 0;2079 pTaskState->IOCReply.SCSIIOError.u32IOCLogInfo = 0;2080 pTaskState->IOCReply.SCSIIOError.u32TransferCount = 0;2081 pTaskState->IOCReply.SCSIIOError.u32SenseCount = sizeof(pTaskState->abSenseBuffer);2082 pTaskState->IOCReply.SCSIIOError.u32ResponseInfo = 0;2083 2084 lsilogicFinishAddressReply(pLsiLogic, &pTaskState->IOCReply, true);2085 }2086 }2087 2088 RTMemCacheFree(pLsiLogic->hTaskCache, pTaskState);2089 2163 2090 2164 if (pLsiLogicDevice->cOutstandingRequests == 0 && pLsiLogic->fSignalIdle) … … 3974 4048 } 3975 4049 4050 /** 4051 * Kicks the controller to process pending tasks after the VM was resumed 4052 * or loaded from a saved state. 4053 * 4054 * @returns nothing. 4055 * @param pThis The LsiLogic device instance. 4056 */ 4057 static void lsilogicKick(PLSILOGICSCSI pThis) 4058 { 4059 if (pThis->fNotificationSend) 4060 { 4061 /* Send a notifier to the PDM queue that there are pending requests. */ 4062 PPDMQUEUEITEMCORE pItem = PDMQueueAlloc(pThis->CTX_SUFF(pNotificationQueue)); 4063 AssertMsg(pItem, ("Allocating item for queue failed\n")); 4064 PDMQueueInsert(pThis->CTX_SUFF(pNotificationQueue), (PPDMQUEUEITEMCORE)pItem); 4065 } 4066 else if (pThis->VBoxSCSI.fBusy) 4067 { 4068 /* The BIOS had a request active when we got suspended. Resume it. */ 4069 int rc = lsilogicPrepareBIOSSCSIRequest(pThis); 4070 AssertRC(rc); 4071 } 4072 4073 } 4074 3976 4075 static DECLCALLBACK(int) lsilogicLiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass) 3977 4076 { … … 4138 4237 SSMR3PutBool (pSSM, pLsiLogic->VBoxSCSI.fBusy); 4139 4238 SSMR3PutU8 (pSSM, pLsiLogic->VBoxSCSI.enmState); 4140 if (pLsiLogic->VBoxSCSI.cb CDB)4239 if (pLsiLogic->VBoxSCSI.cbBuf) 4141 4240 SSMR3PutMem(pSSM, pLsiLogic->VBoxSCSI.pBuf, pLsiLogic->VBoxSCSI.cbBuf); 4142 4241 4143 4242 return SSMR3PutU32(pSSM, ~0); 4243 } 4244 4245 static DECLCALLBACK(int) lsilogicLoadDone(PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 4246 { 4247 PLSILOGICSCSI pThis = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI); 4248 4249 lsilogicKick(pThis); 4250 return VINF_SUCCESS; 4144 4251 } 4145 4252 … … 4412 4519 SSMR3GetBool(pSSM, (bool *)&pLsiLogic->VBoxSCSI.fBusy); 4413 4520 SSMR3GetU8 (pSSM, (uint8_t *)&pLsiLogic->VBoxSCSI.enmState); 4414 if (pLsiLogic->VBoxSCSI.cb CDB)4415 { 4416 pLsiLogic->VBoxSCSI.pBuf = (uint8_t *)RTMemAllocZ(pLsiLogic->VBoxSCSI.cb CDB);4521 if (pLsiLogic->VBoxSCSI.cbBuf) 4522 { 4523 pLsiLogic->VBoxSCSI.pBuf = (uint8_t *)RTMemAllocZ(pLsiLogic->VBoxSCSI.cbBuf); 4417 4524 if (!pLsiLogic->VBoxSCSI.pBuf) 4418 4525 { … … 4553 4660 PDMDevHlpSetAsyncNotification(pDevIns, lsilogicR3IsAsyncSuspendOrPowerOffDone); 4554 4661 else 4662 { 4555 4663 ASMAtomicWriteBool(&pThis->fSignalIdle, false); 4664 4665 AssertMsg(!pThis->fNotificationSend, ("The PDM Queue should be empty at this point\n")); 4666 4667 if (pThis->fRedo) 4668 { 4669 /* 4670 * We have tasks which we need to redo. Put the message frame addresses 4671 * into the request queue (we save the requests). 4672 * Guest execution is suspended at this point so there is no race between us and 4673 * lsilogicRegisterWrite. 4674 */ 4675 PLSILOGICTASKSTATE pTaskState = pThis->pTasksRedoHead; 4676 4677 pThis->pTasksRedoHead = NULL; 4678 4679 while (pTaskState) 4680 { 4681 PLSILOGICTASKSTATE pFree; 4682 4683 if (!pTaskState->fBIOS) 4684 { 4685 /* Write only the lower 32bit part of the address. */ 4686 ASMAtomicWriteU32(&pThis->CTX_SUFF(pRequestQueueBase)[pThis->uRequestQueueNextEntryFreeWrite], 4687 pTaskState->GCPhysMessageFrameAddr & UINT32_C(0xffffffff)); 4688 4689 pThis->uRequestQueueNextEntryFreeWrite++; 4690 pThis->uRequestQueueNextEntryFreeWrite %= pThis->cRequestQueueEntries; 4691 4692 pThis->fNotificationSend = true; 4693 } 4694 else 4695 { 4696 AssertMsg(!pTaskState->pRedoNext, ("Only one BIOS task can be active!\n")); 4697 vboxscsiSetRequestRedo(&pThis->VBoxSCSI, &pTaskState->PDMScsiRequest); 4698 } 4699 4700 pFree = pTaskState; 4701 pTaskState = pTaskState->pRedoNext; 4702 4703 RTMemCacheFree(pThis->hTaskCache, pFree); 4704 } 4705 pThis->fRedo = false; 4706 } 4707 } 4556 4708 } 4557 4709 … … 4565 4717 Log(("lsilogicSuspend\n")); 4566 4718 lsilogicR3SuspendOrPowerOff(pDevIns); 4719 } 4720 4721 /** 4722 * Resume notification. 4723 * 4724 * @param pDevIns The device instance data. 4725 */ 4726 static DECLCALLBACK(void) lsilogicResume(PPDMDEVINS pDevIns) 4727 { 4728 PLSILOGICSCSI pThis = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI); 4729 4730 Log(("lsilogicResume\n")); 4731 4732 lsilogicKick(pThis); 4567 4733 } 4568 4734 … … 5034 5200 5035 5201 /* Register save state handlers. */ 5036 rc = PDMDevHlpSSMRegister3(pDevIns, LSILOGIC_SAVED_STATE_VERSION, sizeof(*pThis), 5037 lsilogicLiveExec, lsilogicSaveExec, lsilogicLoadExec); 5202 rc = PDMDevHlpSSMRegisterEx(pDevIns, LSILOGIC_SAVED_STATE_VERSION, sizeof(*pThis), NULL, 5203 NULL, lsilogicLiveExec, NULL, 5204 NULL, lsilogicSaveExec, NULL, 5205 NULL, lsilogicLoadExec, lsilogicLoadDone); 5038 5206 if (RT_FAILURE(rc)) 5039 5207 return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic cannot register save state handlers")); … … 5097 5265 lsilogicSuspend, 5098 5266 /* pfnResume */ 5099 NULL,5267 lsilogicResume, 5100 5268 /* pfnAttach */ 5101 5269 lsilogicAttach, … … 5153 5321 lsilogicSuspend, 5154 5322 /* pfnResume */ 5155 NULL,5323 lsilogicResume, 5156 5324 /* pfnAttach */ 5157 5325 lsilogicAttach, -
trunk/src/VBox/Devices/Storage/DrvSCSI.cpp
r30384 r32983 112 112 #define PDMIBLOCKASYNCPORT_2_DRVSCSI(pInterface) ( (PDRVSCSI)((uintptr_t)pInterface - RT_OFFSETOF(DRVSCSI, IPortAsync)) ) 113 113 114 static int drvscsiIsRedoPossible(int rc) 115 { 116 if ( rc == VERR_DISK_FULL 117 || rc == VERR_FILE_TOO_BIG 118 || rc == VERR_BROKEN_PIPE 119 || rc == VERR_NET_CONNECTION_REFUSED) 120 return true; 121 122 return false; 123 } 124 114 125 static int drvscsiProcessRequestOne(PDRVSCSI pThis, VSCSIIOREQ hVScsiIoReq) 115 126 { … … 152 163 pThis->pLed->Actual.s.fReading = 0; 153 164 if (RT_FAILURE(rc)) 154 AssertMsgFailed(("%s: Failed to read data %Rrc\n", __FUNCTION__, rc));165 break; 155 166 STAM_REL_COUNTER_ADD(&pThis->StatBytesRead, cbProcess); 156 167 } … … 162 173 pThis->pLed->Actual.s.fWriting = 0; 163 174 if (RT_FAILURE(rc)) 164 AssertMsgFailed(("%s: Failed to write data %Rrc\n", __FUNCTION__, rc));175 break; 165 176 STAM_REL_COUNTER_ADD(&pThis->StatBytesWritten, cbProcess); 166 177 } … … 179 190 } 180 191 181 VSCSIIoReqCompleted(hVScsiIoReq, rc); 192 if (RT_SUCCESS(rc)) 193 VSCSIIoReqCompleted(hVScsiIoReq, rc, false /* fRedoPossible */); 194 else 195 VSCSIIoReqCompleted(hVScsiIoReq, rc, drvscsiIsRedoPossible(rc)); 182 196 183 197 return VINF_SUCCESS; … … 208 222 AssertMsg(enmTxDir == VSCSIIOREQTXDIR_FLUSH, ("Invalid transfer direction %u\n", enmTxDir)); 209 223 210 VSCSIIoReqCompleted(hVScsiIoReq, rc); 224 if (RT_SUCCESS(rc)) 225 VSCSIIoReqCompleted(hVScsiIoReq, rc, false /* fRedoPossible */); 226 else 227 VSCSIIoReqCompleted(hVScsiIoReq, rc, drvscsiIsRedoPossible(rc)); 211 228 212 229 return VINF_SUCCESS; … … 296 313 AssertMsg(enmTxDir == VSCSIIOREQTXDIR_FLUSH, ("Invalid transfer direction %u\n", enmTxDir)); 297 314 298 VSCSIIoReqCompleted(hVScsiIoReq, VINF_SUCCESS );315 VSCSIIoReqCompleted(hVScsiIoReq, VINF_SUCCESS, false); 299 316 } 300 317 else if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS) … … 309 326 AssertMsg(enmTxDir == VSCSIIOREQTXDIR_FLUSH, ("Invalid transfer direction %u\n", enmTxDir)); 310 327 311 VSCSIIoReqCompleted(hVScsiIoReq, rc );328 VSCSIIoReqCompleted(hVScsiIoReq, rc, drvscsiIsRedoPossible(rc)); 312 329 rc = VINF_SUCCESS; 313 330 } … … 326 343 327 344 static void drvscsiVScsiReqCompleted(VSCSIDEVICE hVScsiDevice, void *pVScsiDeviceUser, 328 void *pVScsiReqUser, int rcReq) 345 void *pVScsiReqUser, int rcScsiCode, bool fRedoPossible, 346 int rcReq) 329 347 { 330 348 PDRVSCSI pThis = (PDRVSCSI)pVScsiDeviceUser; … … 333 351 334 352 pThis->pDevScsiPort->pfnSCSIRequestCompleted(pThis->pDevScsiPort, (PPDMSCSIREQUEST)pVScsiReqUser, 335 rc Req);353 rcScsiCode, fRedoPossible, rcReq); 336 354 337 355 if (RT_UNLIKELY(pThis->fDummySignal) && !pThis->StatIoDepth) -
trunk/src/VBox/Devices/Storage/DrvSCSIHost.cpp
r28800 r32983 316 316 } 317 317 /* Notify device that request finished. */ 318 rc = pThis->pDevScsiPort->pfnSCSIRequestCompleted(pThis->pDevScsiPort, pRequest, SCSI_STATUS_OK );318 rc = pThis->pDevScsiPort->pfnSCSIRequestCompleted(pThis->pDevScsiPort, pRequest, SCSI_STATUS_OK, false, VINF_SUCCESS); 319 319 AssertMsgRC(rc, ("Notifying device above failed rc=%Rrc\n", rc)); 320 320 -
trunk/src/VBox/Devices/Storage/UsbMsd.cpp
r28800 r32983 746 746 * @interface_method_impl{PDMISCSIPORT,pfnSCSIRequestCompleted} 747 747 */ 748 static DECLCALLBACK(int) usbMsdLun0ScsiRequestCompleted(PPDMISCSIPORT pInterface, PPDMSCSIREQUEST pSCSIRequest, int rcCompletion) 748 static DECLCALLBACK(int) usbMsdLun0ScsiRequestCompleted(PPDMISCSIPORT pInterface, PPDMSCSIREQUEST pSCSIRequest, 749 int rcCompletion, bool fRedo, int rcReq) 749 750 { 750 751 PUSBMSD pThis = RT_FROM_MEMBER(pInterface, USBMSD, Lun0.IScsiPort); … … 894 895 pReq->ScsiReqSense[13] = 0; /* Should be ASCQ but it has the same value for success. */ 895 896 896 usbMsdLun0ScsiRequestCompleted(&pThis->Lun0.IScsiPort, &pReq->ScsiReq, SCSI_STATUS_CHECK_CONDITION );897 usbMsdLun0ScsiRequestCompleted(&pThis->Lun0.IScsiPort, &pReq->ScsiReq, SCSI_STATUS_CHECK_CONDITION, false, VINF_SUCCESS); 897 898 return VINF_SUCCESS; 898 899 } … … 946 947 947 948 /* Do normal completion. */ 948 usbMsdLun0ScsiRequestCompleted(&pThis->Lun0.IScsiPort, &pReq->ScsiReq, SCSI_STATUS_OK );949 usbMsdLun0ScsiRequestCompleted(&pThis->Lun0.IScsiPort, &pReq->ScsiReq, SCSI_STATUS_OK, false, VINF_SUCCESS); 949 950 return VINF_SUCCESS; 950 951 } … … 1274 1275 LogFlow(("usbMsdHandleBulkDevToHost: Added %p:%s to the to-host queue\n", pUrb, pUrb->pszDesc)); 1275 1276 1276 usbMsdLun0ScsiRequestCompleted(&pThis->Lun0.IScsiPort, &pReq->ScsiReq, SCSI_STATUS_OK );1277 usbMsdLun0ScsiRequestCompleted(&pThis->Lun0.IScsiPort, &pReq->ScsiReq, SCSI_STATUS_OK, false, VINF_SUCCESS); 1277 1278 return VINF_SUCCESS; 1278 1279 } -
trunk/src/VBox/Devices/Storage/VBoxSCSI.cpp
r28800 r32983 271 271 if (pVBoxSCSI->uTxDir == VBOXSCSI_TXDIR_FROM_DEVICE) 272 272 { 273 Assert(!pVBoxSCSI->pBuf); 273 if (pVBoxSCSI->pBuf) 274 RTMemFree(pVBoxSCSI->pBuf); 275 274 276 pVBoxSCSI->pBuf = (uint8_t *)RTMemAllocZ(pVBoxSCSI->cbBuf); 275 277 if (!pVBoxSCSI->pBuf) … … 277 279 } 278 280 279 /* *Allocate scatter gather element. */281 /* Allocate scatter gather element. */ 280 282 pScsiRequest->paScatterGatherHead = (PRTSGSEG)RTMemAllocZ(sizeof(RTSGSEG) * 1); /* Only one element. */ 281 283 if (!pScsiRequest->paScatterGatherHead) … … 286 288 } 287 289 288 /* *Allocate sense buffer. */290 /* Allocate sense buffer. */ 289 291 pScsiRequest->cbSenseBuffer = 18; 290 292 pScsiRequest->pbSenseBuffer = (uint8_t *)RTMemAllocZ(pScsiRequest->cbSenseBuffer); … … 385 387 } 386 388 389 void vboxscsiSetRequestRedo(PVBOXSCSI pVBoxSCSI, PPDMSCSIREQUEST pScsiRequest) 390 { 391 AssertMsg(pVBoxSCSI->fBusy, ("No request to redo\n")); 392 393 RTMemFree(pScsiRequest->paScatterGatherHead); 394 RTMemFree(pScsiRequest->pbSenseBuffer); 395 396 if (pVBoxSCSI->uTxDir == VBOXSCSI_TXDIR_FROM_DEVICE) 397 { 398 AssertPtr(pVBoxSCSI->pBuf); 399 } 400 } 401 -
trunk/src/VBox/Devices/Storage/VBoxSCSI.h
r28800 r32983 124 124 int vboxscsiSetupRequest(PVBOXSCSI pVBoxSCSI, PPDMSCSIREQUEST pScsiRequest, uint32_t *puTargetDevice); 125 125 int vboxscsiRequestFinished(PVBOXSCSI pVBoxSCSI, PPDMSCSIREQUEST pScsiRequest); 126 void vboxscsiSetRequestRedo(PVBOXSCSI pVBoxSCSI, PPDMSCSIREQUEST pScsiRequest); 126 127 int vboxscsiWriteString(PPDMDEVINS pDevIns, PVBOXSCSI pVBoxSCSI, uint8_t iRegister, 127 128 RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb); -
trunk/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp
r28800 r32983 109 109 } 110 110 111 /** 112 * Completesa SCSI request and calls the completion handler. 113 * 114 * @returns nothing. 115 * @param pVScsiDevice The virtual SCSI device. 116 * @param pVScsiReq The request which completed. 117 * @param rcReq The status code 118 * One of the SCSI_STATUS_* #defines. 119 */ 111 120 112 void vscsiDeviceReqComplete(PVSCSIDEVICEINT pVScsiDevice, PVSCSIREQINT pVScsiReq, 121 int rc Req)113 int rcScsiCode, bool fRedoPossible, int rcReq) 122 114 { 123 115 pVScsiDevice->pfnVScsiReqCompleted(pVScsiDevice, pVScsiDevice->pvVScsiDeviceUser, 124 pVScsiReq->pvVScsiReqUser, rcReq); 116 pVScsiReq->pvVScsiReqUser, rcScsiCode, fRedoPossible, 117 rcReq); 125 118 126 119 RTMemCacheFree(pVScsiDevice->hCacheReq, pVScsiReq); … … 294 287 295 288 vscsiDeviceReqComplete(pVScsiDevice, pVScsiReq, 296 SCSI_STATUS_CHECK_CONDITION );289 SCSI_STATUS_CHECK_CONDITION, false, VINF_SUCCESS); 297 290 } 298 291 } 299 292 else 300 293 vscsiDeviceReqComplete(pVScsiDevice, pVScsiReq, 301 rcReq );294 rcReq, false, VINF_SUCCESS); 302 295 303 296 return rc; -
trunk/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h
r28800 r32983 189 189 * @param pVScsiDevice The virtual SCSI device. 190 190 * @param pVScsiReq The request which completed. 191 * @param rc ReqThe status code191 * @param rcScsiCode The status code 192 192 * One of the SCSI_STATUS_* #defines. 193 * @param fRedoPossible Flag whether redo is possible. 194 * @param rcReq Informational return code of the request. 193 195 */ 194 196 void vscsiDeviceReqComplete(PVSCSIDEVICEINT pVScsiDevice, PVSCSIREQINT pVScsiReq, 195 int rc Req);197 int rcScsiCode, bool fRedoPossible, int rcReq); 196 198 197 199 /** -
trunk/src/VBox/Devices/Storage/VSCSI/VSCSIIoReq.cpp
r28800 r32983 93 93 94 94 95 VBOXDDU_DECL(int) VSCSIIoReqCompleted(VSCSIIOREQ hVScsiIoReq, int rcIoReq )95 VBOXDDU_DECL(int) VSCSIIoReqCompleted(VSCSIIOREQ hVScsiIoReq, int rcIoReq, bool fRedoPossible) 96 96 { 97 97 PVSCSIIOREQINT pVScsiIoReq = hVScsiIoReq; … … 115 115 if (RT_SUCCESS(rcIoReq)) 116 116 rcReq = vscsiReqSenseOkSet(pVScsiReq); 117 else if (!fRedoPossible) 118 { 119 /** @todo Not 100% correct for the write case as the 0x00 ASCQ for write errors 120 * is not used for SBC devices. */ 121 rcReq = vscsiReqSenseErrorSet(pVScsiReq, SCSI_SENSE_MEDIUM_ERROR, 122 pVScsiIoReq->enmTxDir == VSCSIIOREQTXDIR_READ 123 ? SCSI_ASC_READ_ERROR 124 : SCSI_ASC_WRITE_ERROR); 125 } 126 else 127 rcReq = SCSI_STATUS_CHECK_CONDITION; 117 128 118 129 /* Free the I/O request */ … … 120 131 121 132 /* Notify completion of the SCSI request. */ 122 vscsiDeviceReqComplete(pVScsiLun->pVScsiDevice, pVScsiReq, rcReq );133 vscsiDeviceReqComplete(pVScsiLun->pVScsiDevice, pVScsiReq, rcReq, fRedoPossible, rcIoReq); 123 134 124 135 return VINF_SUCCESS; -
trunk/src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp
r30174 r32983 302 302 { 303 303 rcReq = vscsiReqSenseErrorSet(pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR); 304 vscsiDeviceReqComplete(pVScsiLun->pVScsiDevice, pVScsiReq, rcReq );304 vscsiDeviceReqComplete(pVScsiLun->pVScsiDevice, pVScsiReq, rcReq, false, VINF_SUCCESS); 305 305 } 306 306 else … … 317 317 } 318 318 else /* Request completed */ 319 vscsiDeviceReqComplete(pVScsiLun->pVScsiDevice, pVScsiReq, rcReq );319 vscsiDeviceReqComplete(pVScsiLun->pVScsiDevice, pVScsiReq, rcReq, false, VINF_SUCCESS); 320 320 321 321 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.