Changeset 89193 in vbox for trunk/src/VBox/Devices/Storage
- Timestamp:
- May 20, 2021 9:26:19 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 144534
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
r88643 r89193 51 51 *********************************************************************************************************************************/ 52 52 /** The current saved state version. */ 53 #define LSILOGIC_SAVED_STATE_VERSION 5 53 #define LSILOGIC_SAVED_STATE_VERSION 6 54 /** The saved state version used by VirtualBox before removal of the 55 * VBoxSCSI BIOS interface. */ 56 #define LSILOGIC_SAVED_STATE_VERSION_PRE_VBOXSCSI_REMOVAL 5 54 57 /** The saved state version used by VirtualBox before the diagnostic 55 58 * memory access was implemented. */ 56 #define LSILOGIC_SAVED_STATE_VERSION_PRE_DIAG_MEM 459 #define LSILOGIC_SAVED_STATE_VERSION_PRE_DIAG_MEM 4 57 60 /** The saved state version used by VirtualBox before the doorbell status flag 58 61 * was changed from bool to a 32bit enum. */ 59 #define LSILOGIC_SAVED_STATE_VERSION_BOOL_DOORBELL 362 #define LSILOGIC_SAVED_STATE_VERSION_BOOL_DOORBELL 3 60 63 /** The saved state version used by VirtualBox before SAS support was added. */ 61 #define LSILOGIC_SAVED_STATE_VERSION_PRE_SAS 264 #define LSILOGIC_SAVED_STATE_VERSION_PRE_SAS 2 62 65 /** The saved state version used by VirtualBox 3.0 and earlier. It does not 63 66 * include the device config part. */ 64 #define LSILOGIC_SAVED_STATE_VERSION_VBOX_30 167 #define LSILOGIC_SAVED_STATE_VERSION_VBOX_30 1 65 68 66 69 /** Maximum number of entries in the release log. */ … … 289 292 /** Flag whether the worker thread is sleeping. */ 290 293 volatile bool fWrkThreadSleeping; 291 /** Flag whether a request from the BIOS is pending which the 292 * worker thread needs to process. */ 293 volatile bool fBiosReqPending; 294 bool fPadding3; 294 bool afPadding3[2]; 295 295 296 296 /** Current address to read from or write to in the diagnostic memory region. */ … … 337 337 /** Pointer to the configuration page area. */ 338 338 R3PTRTYPE(PMptConfigurationPagesSupported) pConfigurationPages; 339 340 /** BIOS emulation. */341 VBOXSCSI VBoxSCSI;342 339 343 340 /** Current size of the memory regions. */ … … 411 408 /** Pointer to the sense buffer. */ 412 409 uint8_t abSenseBuffer[18]; 413 /** Flag whether the request was issued from the BIOS. */414 bool fBIOS;415 410 /** SCSI status code. */ 416 411 uint8_t u8ScsiSts; … … 2225 2220 * @param rcReq Status code of the request. 2226 2221 */ 2227 static void lsilogicR3ReqComplete(PPDMDEVINS pDevIns, PLSILOGICSCSI pThis, PLSILOGIC SCSICC pThisCC, PLSILOGICREQ pReq, int rcReq)2222 static void lsilogicR3ReqComplete(PPDMDEVINS pDevIns, PLSILOGICSCSI pThis, PLSILOGICREQ pReq, int rcReq) 2228 2223 { 2229 2224 PLSILOGICDEVICE pTgtDev = pReq->pTargetDevice; 2230 2231 if (!pReq->fBIOS) 2232 { 2233 RTGCPHYS GCPhysAddrSenseBuffer; 2234 2235 GCPhysAddrSenseBuffer = pReq->GuestRequest.SCSIIO.u32SenseBufferLowAddress; 2236 GCPhysAddrSenseBuffer |= ((uint64_t)pThis->u32SenseBufferHighAddr << 32); 2237 2238 /* Copy the sense buffer over. */ 2239 if (pReq->GuestRequest.SCSIIO.u8SenseBufferLength > 0) 2240 PDMDevHlpPCIPhysWriteMeta(pDevIns, GCPhysAddrSenseBuffer, pReq->abSenseBuffer, 2241 RT_UNLIKELY( pReq->GuestRequest.SCSIIO.u8SenseBufferLength 2242 < sizeof(pReq->abSenseBuffer)) 2243 ? pReq->GuestRequest.SCSIIO.u8SenseBufferLength 2244 : sizeof(pReq->abSenseBuffer)); 2245 2246 if (RT_SUCCESS(rcReq) && RT_LIKELY(pReq->u8ScsiSts == SCSI_STATUS_OK)) 2247 { 2248 uint32_t u32MsgCtx = pReq->GuestRequest.SCSIIO.u32MessageContext; 2249 2250 /* Free the request before posting completion. */ 2251 pTgtDev->pDrvMediaEx->pfnIoReqFree(pTgtDev->pDrvMediaEx, pReq->hIoReq); 2252 lsilogicR3FinishContextReply(pDevIns, pThis, u32MsgCtx); 2253 } 2254 else 2255 { 2256 MptReplyUnion IOCReply; 2257 RT_ZERO(IOCReply); 2258 2259 /* The SCSI target encountered an error during processing post a reply. */ 2260 IOCReply.SCSIIOError.u8TargetID = pReq->GuestRequest.SCSIIO.u8TargetID; 2261 IOCReply.SCSIIOError.u8Bus = pReq->GuestRequest.SCSIIO.u8Bus; 2262 IOCReply.SCSIIOError.u8MessageLength = 8; 2263 IOCReply.SCSIIOError.u8Function = pReq->GuestRequest.SCSIIO.u8Function; 2264 IOCReply.SCSIIOError.u8CDBLength = pReq->GuestRequest.SCSIIO.u8CDBLength; 2265 IOCReply.SCSIIOError.u8SenseBufferLength = pReq->GuestRequest.SCSIIO.u8SenseBufferLength; 2266 IOCReply.SCSIIOError.u8MessageFlags = pReq->GuestRequest.SCSIIO.u8MessageFlags; 2267 IOCReply.SCSIIOError.u32MessageContext = pReq->GuestRequest.SCSIIO.u32MessageContext; 2268 IOCReply.SCSIIOError.u8SCSIStatus = pReq->u8ScsiSts; 2269 IOCReply.SCSIIOError.u8SCSIState = MPT_SCSI_IO_ERROR_SCSI_STATE_AUTOSENSE_VALID; 2270 IOCReply.SCSIIOError.u16IOCStatus = 0; 2271 IOCReply.SCSIIOError.u32IOCLogInfo = 0; 2272 IOCReply.SCSIIOError.u32TransferCount = 0; 2273 IOCReply.SCSIIOError.u32SenseCount = sizeof(pReq->abSenseBuffer); 2274 IOCReply.SCSIIOError.u32ResponseInfo = 0; 2275 2276 /* Free the request before posting completion. */ 2277 pTgtDev->pDrvMediaEx->pfnIoReqFree(pTgtDev->pDrvMediaEx, pReq->hIoReq); 2278 lsilogicFinishAddressReply(pDevIns, pThis, &IOCReply, false); 2279 } 2225 RTGCPHYS GCPhysAddrSenseBuffer; 2226 2227 GCPhysAddrSenseBuffer = pReq->GuestRequest.SCSIIO.u32SenseBufferLowAddress; 2228 GCPhysAddrSenseBuffer |= ((uint64_t)pThis->u32SenseBufferHighAddr << 32); 2229 2230 /* Copy the sense buffer over. */ 2231 if (pReq->GuestRequest.SCSIIO.u8SenseBufferLength > 0) 2232 PDMDevHlpPCIPhysWriteMeta(pDevIns, GCPhysAddrSenseBuffer, pReq->abSenseBuffer, 2233 RT_UNLIKELY( pReq->GuestRequest.SCSIIO.u8SenseBufferLength 2234 < sizeof(pReq->abSenseBuffer)) 2235 ? pReq->GuestRequest.SCSIIO.u8SenseBufferLength 2236 : sizeof(pReq->abSenseBuffer)); 2237 2238 if (RT_SUCCESS(rcReq) && RT_LIKELY(pReq->u8ScsiSts == SCSI_STATUS_OK)) 2239 { 2240 uint32_t u32MsgCtx = pReq->GuestRequest.SCSIIO.u32MessageContext; 2241 2242 /* Free the request before posting completion. */ 2243 pTgtDev->pDrvMediaEx->pfnIoReqFree(pTgtDev->pDrvMediaEx, pReq->hIoReq); 2244 lsilogicR3FinishContextReply(pDevIns, pThis, u32MsgCtx); 2280 2245 } 2281 2246 else 2282 2247 { 2283 uint8_t u8ScsiSts = pReq->u8ScsiSts; 2248 MptReplyUnion IOCReply; 2249 RT_ZERO(IOCReply); 2250 2251 /* The SCSI target encountered an error during processing post a reply. */ 2252 IOCReply.SCSIIOError.u8TargetID = pReq->GuestRequest.SCSIIO.u8TargetID; 2253 IOCReply.SCSIIOError.u8Bus = pReq->GuestRequest.SCSIIO.u8Bus; 2254 IOCReply.SCSIIOError.u8MessageLength = 8; 2255 IOCReply.SCSIIOError.u8Function = pReq->GuestRequest.SCSIIO.u8Function; 2256 IOCReply.SCSIIOError.u8CDBLength = pReq->GuestRequest.SCSIIO.u8CDBLength; 2257 IOCReply.SCSIIOError.u8SenseBufferLength = pReq->GuestRequest.SCSIIO.u8SenseBufferLength; 2258 IOCReply.SCSIIOError.u8MessageFlags = pReq->GuestRequest.SCSIIO.u8MessageFlags; 2259 IOCReply.SCSIIOError.u32MessageContext = pReq->GuestRequest.SCSIIO.u32MessageContext; 2260 IOCReply.SCSIIOError.u8SCSIStatus = pReq->u8ScsiSts; 2261 IOCReply.SCSIIOError.u8SCSIState = MPT_SCSI_IO_ERROR_SCSI_STATE_AUTOSENSE_VALID; 2262 IOCReply.SCSIIOError.u16IOCStatus = 0; 2263 IOCReply.SCSIIOError.u32IOCLogInfo = 0; 2264 IOCReply.SCSIIOError.u32TransferCount = 0; 2265 IOCReply.SCSIIOError.u32SenseCount = sizeof(pReq->abSenseBuffer); 2266 IOCReply.SCSIIOError.u32ResponseInfo = 0; 2267 2268 /* Free the request before posting completion. */ 2284 2269 pTgtDev->pDrvMediaEx->pfnIoReqFree(pTgtDev->pDrvMediaEx, pReq->hIoReq); 2285 int rc = vboxscsiRequestFinished(&pThisCC->VBoxSCSI, u8ScsiSts); 2286 AssertMsgRC(rc, ("Finishing BIOS SCSI request failed rc=%Rrc\n", rc)); 2270 lsilogicFinishAddressReply(pDevIns, pThis, &IOCReply, false); 2287 2271 } 2288 2272 … … 2335 2319 pLsiReq->pTargetDevice = pTgtDev; 2336 2320 pLsiReq->GCPhysMessageFrameAddr = GCPhysMessageFrameAddr; 2337 pLsiReq->fBIOS = false;2338 2321 pLsiReq->GCPhysSgStart = GCPhysMessageFrameAddr + sizeof(MptSCSIIORequest); 2339 2322 pLsiReq->cChainOffset = pGuestReq->SCSIIO.u8ChainOffset; … … 2366 2349 &pLsiReq->u8ScsiSts, 30 * RT_MS_1SEC); 2367 2350 if (rc != VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS) 2368 lsilogicR3ReqComplete(pDevIns, pThis, p ThisCC, pLsiReq, rc);2351 lsilogicR3ReqComplete(pDevIns, pThis, pLsiReq, rc); 2369 2352 2370 2353 return VINF_SUCCESS; … … 2456 2439 PLSILOGICDEVICE pTgtDev = RT_FROM_MEMBER(pInterface, LSILOGICDEVICE, IMediaExPort); 2457 2440 PPDMDEVINS pDevIns = pTgtDev->pDevIns; 2458 PLSILOGICSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PLSILOGICSCSICC);2459 2441 PLSILOGICREQ pReq = (PLSILOGICREQ)pvIoReqAlloc; 2460 2442 2461 size_t cbCopied = 0; 2462 if (!pReq->fBIOS) 2463 cbCopied = lsilogicR3CopySgBufToGuest(pDevIns, pReq, pSgBuf, offDst, cbCopy); 2464 else 2465 cbCopied = vboxscsiCopyToBuf(&pThisCC->VBoxSCSI, pSgBuf, offDst, cbCopy); 2443 size_t cbCopied = lsilogicR3CopySgBufToGuest(pDevIns, pReq, pSgBuf, offDst, cbCopy); 2466 2444 return cbCopied == cbCopy ? VINF_SUCCESS : VERR_PDM_MEDIAEX_IOBUF_OVERFLOW; 2467 2445 } … … 2477 2455 PLSILOGICDEVICE pTgtDev = RT_FROM_MEMBER(pInterface, LSILOGICDEVICE, IMediaExPort); 2478 2456 PPDMDEVINS pDevIns = pTgtDev->pDevIns; 2479 PLSILOGICSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PLSILOGICSCSICC);2480 2457 PLSILOGICREQ pReq = (PLSILOGICREQ)pvIoReqAlloc; 2481 2458 2482 size_t cbCopied = 0; 2483 if (!pReq->fBIOS) 2484 cbCopied = lsilogicR3CopySgBufFromGuest(pDevIns, pReq, pSgBuf, offSrc, cbCopy); 2485 else 2486 cbCopied = vboxscsiCopyFromBuf(&pThisCC->VBoxSCSI, pSgBuf, offSrc, cbCopy); 2459 size_t cbCopied = lsilogicR3CopySgBufFromGuest(pDevIns, pReq, pSgBuf, offSrc, cbCopy); 2487 2460 return cbCopied == cbCopy ? VINF_SUCCESS : VERR_PDM_MEDIAEX_IOBUF_UNDERRUN; 2488 2461 } … … 2498 2471 PPDMDEVINS pDevIns = pTgtDev->pDevIns; 2499 2472 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI); 2500 PLSILOGICSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PLSILOGICSCSICC); 2501 lsilogicR3ReqComplete(pDevIns, pThis, pThisCC, (PLSILOGICREQ)pvIoReqAlloc, rcReq); 2473 lsilogicR3ReqComplete(pDevIns, pThis, (PLSILOGICREQ)pvIoReqAlloc, rcReq); 2502 2474 return VINF_SUCCESS; 2503 2475 } … … 3902 3874 } 3903 3875 3904 return rc;3905 }3906 3907 /**3908 * @callback_method_impl{FNIOMIOPORTIN, Legacy ISA port.}3909 */3910 static DECLCALLBACK(VBOXSTRICTRC)3911 lsilogicR3IsaIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t *pu32, unsigned cb)3912 {3913 RT_NOREF(pvUser, cb);3914 PLSILOGICSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PLSILOGICSCSICC);3915 3916 ASSERT_GUEST(cb == 1);3917 3918 int rc = vboxscsiReadRegister(&pThisCC->VBoxSCSI, offPort, pu32);3919 AssertMsg(rc == VINF_SUCCESS, ("Unexpected BIOS register read status: %Rrc\n", rc));3920 3921 Log2(("%s: pu32=%p:{%.*Rhxs} offPort=%d rc=%Rrc\n", __FUNCTION__, pu32, 1, pu32, offPort, rc));3922 3923 return rc;3924 }3925 3926 /**3927 * Prepares a request from the BIOS.3928 *3929 * @returns VBox status code.3930 * @param pThis Pointer to the shared LsiLogic device state.3931 * @param pThisCC Pointer to the ring-3 LsiLogic device state.3932 */3933 static int lsilogicR3PrepareBiosScsiRequest(PLSILOGICSCSI pThis, PLSILOGICSCSICC pThisCC)3934 {3935 int rc;3936 uint32_t uTargetDevice;3937 uint32_t uLun;3938 uint8_t *pbCdb;3939 size_t cbCdb;3940 size_t cbBuf;3941 3942 rc = vboxscsiSetupRequest(&pThisCC->VBoxSCSI, &uLun, &pbCdb, &cbCdb, &cbBuf, &uTargetDevice);3943 AssertMsgRCReturn(rc, ("Setting up SCSI request failed rc=%Rrc\n", rc), rc);3944 3945 if ( uTargetDevice < pThis->cDeviceStates3946 && pThisCC->paDeviceStates[uTargetDevice].pDrvBase)3947 {3948 PLSILOGICDEVICE pTgtDev = &pThisCC->paDeviceStates[uTargetDevice];3949 PDMMEDIAEXIOREQ hIoReq;3950 PLSILOGICREQ pReq;3951 3952 rc = pTgtDev->pDrvMediaEx->pfnIoReqAlloc(pTgtDev->pDrvMediaEx, &hIoReq, (void **)&pReq,3953 0, PDMIMEDIAEX_F_SUSPEND_ON_RECOVERABLE_ERR);3954 AssertMsgRCReturn(rc, ("Getting task from cache failed rc=%Rrc\n", rc), rc);3955 3956 pReq->fBIOS = true;3957 pReq->hIoReq = hIoReq;3958 pReq->pTargetDevice = pTgtDev;3959 3960 ASMAtomicIncU32(&pTgtDev->cOutstandingRequests);3961 3962 rc = pTgtDev->pDrvMediaEx->pfnIoReqSendScsiCmd(pTgtDev->pDrvMediaEx, pReq->hIoReq, uLun,3963 pbCdb, cbCdb, PDMMEDIAEXIOREQSCSITXDIR_UNKNOWN, NULL,3964 cbBuf, NULL, 0, NULL, &pReq->u8ScsiSts, 30 * RT_MS_1SEC);3965 if (rc == VINF_SUCCESS || rc != VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS)3966 {3967 uint8_t u8ScsiSts = pReq->u8ScsiSts;3968 pTgtDev->pDrvMediaEx->pfnIoReqFree(pTgtDev->pDrvMediaEx, pReq->hIoReq);3969 rc = vboxscsiRequestFinished(&pThisCC->VBoxSCSI, u8ScsiSts);3970 }3971 else if (rc == VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS)3972 rc = VINF_SUCCESS;3973 3974 return rc;3975 }3976 3977 /* Device is not present. */3978 AssertMsg(pbCdb[0] == SCSI_INQUIRY,3979 ("Device is not present but command is not inquiry\n"));3980 3981 SCSIINQUIRYDATA ScsiInquiryData;3982 3983 memset(&ScsiInquiryData, 0, sizeof(SCSIINQUIRYDATA));3984 ScsiInquiryData.u5PeripheralDeviceType = SCSI_INQUIRY_DATA_PERIPHERAL_DEVICE_TYPE_UNKNOWN;3985 ScsiInquiryData.u3PeripheralQualifier = SCSI_INQUIRY_DATA_PERIPHERAL_QUALIFIER_NOT_CONNECTED_NOT_SUPPORTED;3986 3987 memcpy(pThisCC->VBoxSCSI.pbBuf, &ScsiInquiryData, 5);3988 3989 rc = vboxscsiRequestFinished(&pThisCC->VBoxSCSI, SCSI_STATUS_OK);3990 AssertMsgRCReturn(rc, ("Finishing BIOS SCSI request failed rc=%Rrc\n", rc), rc);3991 3992 return rc;3993 }3994 3995 /**3996 * @callback_method_impl{FNIOMIOPORTNEWOUT, Legacy ISA port.}3997 */3998 static DECLCALLBACK(VBOXSTRICTRC)3999 lsilogicR3IsaIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t u32, unsigned cb)4000 {4001 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI);4002 PLSILOGICSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PLSILOGICSCSICC);4003 Log2(("#%d %s: pvUser=%#p cb=%d u32=%#x offPort=%#x\n", pDevIns->iInstance, __FUNCTION__, pvUser, cb, u32, offPort));4004 RT_NOREF(pvUser, cb);4005 4006 ASSERT_GUEST(cb == 1);4007 4008 /*4009 * If there is already a request form the BIOS pending ignore this write4010 * because it should not happen.4011 */4012 if (ASMAtomicReadBool(&pThis->fBiosReqPending))4013 return VINF_SUCCESS;4014 4015 int rc = vboxscsiWriteRegister(&pThisCC->VBoxSCSI, offPort, (uint8_t)u32);4016 if (rc == VERR_MORE_DATA)4017 {4018 ASMAtomicXchgBool(&pThis->fBiosReqPending, true);4019 /* Notify the worker thread that there are pending requests. */4020 LogFlowFunc(("Signal event semaphore\n"));4021 rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->hEvtProcess);4022 AssertRC(rc);4023 }4024 else4025 AssertMsg(rc == VINF_SUCCESS, ("Unexpected BIOS register write status: %Rrc\n", rc));4026 4027 return VINF_SUCCESS;4028 }4029 4030 /**4031 * @callback_method_impl{FNIOMIOPORTNEWOUTSTRING,4032 * Port I/O Handler for primary port range OUT string operations.}4033 */4034 static DECLCALLBACK(VBOXSTRICTRC) lsilogicR3IsaIOPortWriteStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort,4035 uint8_t const *pbSrc, uint32_t *pcTransfers, unsigned cb)4036 {4037 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI);4038 PLSILOGICSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PLSILOGICSCSICC);4039 Log2(("#%d %s: pvUser=%#p cb=%d offPort=%#x\n", pDevIns->iInstance, __FUNCTION__, pvUser, cb, offPort));4040 RT_NOREF(pvUser);4041 4042 int rc = vboxscsiWriteString(pDevIns, &pThisCC->VBoxSCSI, offPort, pbSrc, pcTransfers, cb);4043 if (rc == VERR_MORE_DATA)4044 {4045 ASMAtomicXchgBool(&pThis->fBiosReqPending, true);4046 /* Notify the worker thread that there are pending requests. */4047 LogFlowFunc(("Signal event semaphore\n"));4048 rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->hEvtProcess);4049 AssertRC(rc);4050 }4051 else4052 AssertMsg(rc == VINF_SUCCESS, ("Unexpected BIOS register write status: %Rrc\n", rc));4053 4054 return VINF_SUCCESS;4055 }4056 4057 /**4058 * @callback_method_impl{FNIOMIOPORTINSTRING,4059 * Port I/O Handler for primary port range IN string operations.}4060 */4061 static DECLCALLBACK(VBOXSTRICTRC) lsilogicR3IsaIOPortReadStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort,4062 uint8_t *pbDst, uint32_t *pcTransfers, unsigned cb)4063 {4064 PLSILOGICSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PLSILOGICSCSICC);4065 LogFlowFunc(("#%d %s: pvUser=%#p cb=%d offPort=%#x\n", pDevIns->iInstance, __FUNCTION__, pvUser, cb, offPort));4066 RT_NOREF(pvUser);4067 4068 int rc = vboxscsiReadString(pDevIns, &pThisCC->VBoxSCSI, offPort, pbDst, pcTransfers, cb);4069 AssertMsg(rc == VINF_SUCCESS, ("Unexpected BIOS register read status: %Rrc\n", rc));4070 3876 return rc; 4071 3877 } … … 4187 3993 4188 3994 ASMAtomicWriteBool(&pThis->fWrkThreadSleeping, false); 4189 4190 /* Check whether there is a BIOS request pending and process it first. */4191 if (ASMAtomicReadBool(&pThis->fBiosReqPending))4192 {4193 rc = lsilogicR3PrepareBiosScsiRequest(pThis, pThisCC);4194 AssertRC(rc);4195 ASMAtomicXchgBool(&pThis->fBiosReqPending, false);4196 }4197 3995 4198 3996 /* Only process request which arrived before we received the notification. */ … … 4371 4169 for (;;) 4372 4170 { 4373 if (!pReq->fBIOS) 4374 { 4375 /* Write only the lower 32bit part of the address. */ 4376 ASMAtomicWriteU32(&pThis->aRequestQueue[pThis->uRequestQueueNextEntryFreeWrite], 4377 pReq->GCPhysMessageFrameAddr & UINT32_C(0xffffffff)); 4378 4379 pThis->uRequestQueueNextEntryFreeWrite++; 4380 pThis->uRequestQueueNextEntryFreeWrite %= pThis->cRequestQueueEntries; 4381 } 4382 else 4383 { 4384 AssertMsg(!pReq->pRedoNext, ("Only one BIOS task can be active!\n")); 4385 vboxscsiSetRequestRedo(&pThisCC->VBoxSCSI); 4386 } 4171 /* Write only the lower 32bit part of the address. */ 4172 ASMAtomicWriteU32(&pThis->aRequestQueue[pThis->uRequestQueueNextEntryFreeWrite], 4173 pReq->GCPhysMessageFrameAddr & UINT32_C(0xffffffff)); 4174 4175 pThis->uRequestQueueNextEntryFreeWrite++; 4176 pThis->uRequestQueueNextEntryFreeWrite %= pThis->cRequestQueueEntries; 4387 4177 4388 4178 cReqsRedo--; … … 4530 4320 AssertMsgFailed(("Invalid controller type %d\n", pThis->enmCtrlType)); 4531 4321 4532 vboxscsiR3SaveExec(pHlp, &pThisCC->VBoxSCSI, pSSM);4533 4322 return pHlp->pfnSSMPutU32(pSSM, UINT32_MAX); 4534 4323 } … … 4556 4345 int rc; 4557 4346 4558 if ( uVersion != LSILOGIC_SAVED_STATE_VERSION 4559 && uVersion != LSILOGIC_SAVED_STATE_VERSION_PRE_DIAG_MEM 4560 && uVersion != LSILOGIC_SAVED_STATE_VERSION_BOOL_DOORBELL 4561 && uVersion != LSILOGIC_SAVED_STATE_VERSION_PRE_SAS 4562 && uVersion != LSILOGIC_SAVED_STATE_VERSION_VBOX_30) 4347 if ( uVersion > LSILOGIC_SAVED_STATE_VERSION 4348 || uVersion < LSILOGIC_SAVED_STATE_VERSION_VBOX_30) 4563 4349 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; 4564 4350 … … 4867 4653 } 4868 4654 4869 rc = vboxscsiR3LoadExec(pHlp, &pThisCC->VBoxSCSI, pSSM); 4870 if (RT_FAILURE(rc)) 4871 { 4872 LogRel(("LsiLogic: Failed to restore BIOS state: %Rrc.\n", rc)); 4873 return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic: Failed to restore BIOS state\n")); 4874 } 4655 if (uVersion <= LSILOGIC_SAVED_STATE_VERSION_PRE_VBOXSCSI_REMOVAL) 4656 vboxscsiR3LoadExecLegacy(pHlp, pSSM); 4875 4657 4876 4658 uint32_t u32; … … 5147 4929 rc = lsilogicR3HardReset(pDevIns, pThis, pThisCC); 5148 4930 AssertRC(rc); 5149 5150 vboxscsiHwReset(&pThisCC->VBoxSCSI);5151 4931 } 5152 4932 … … 5221 5001 lsilogicR3ConfigurationPagesFree(pThis, pThisCC); 5222 5002 lsilogicR3MemRegionsFree(pThisCC); 5223 vboxscsiDestroy(&pThisCC->VBoxSCSI);5224 5225 5003 return VINF_SUCCESS; 5226 5004 } … … 5241 5019 */ 5242 5020 pThis->hEvtProcess = NIL_SUPSEMEVENT; 5243 pThis->fBiosReqPending = false;5244 5021 RTListInit(&pThisCC->ListMemRegns); 5245 5022 pThis->hMmioReg = NIL_IOMMMIOHANDLE; … … 5260 5037 "ControllerType|" 5261 5038 "NumPorts|" 5262 "Bootable", 5039 "Bootable", /* Keep it for legacy configs, even though it doesn't do anything anymore, see @bugref{4841}. */ 5263 5040 ""); 5264 5041 … … 5316 5093 return PDMDEV_SET_ERROR(pDevIns, rc, 5317 5094 N_("LsiLogic configuration error: failed to read NumPorts as integer")); 5318 5319 bool fBootable;5320 rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "Bootable", &fBootable, true);5321 if (RT_FAILURE(rc))5322 return PDMDEV_SET_ERROR(pDevIns, rc,5323 N_("LsiLogic configuration error: failed to read Bootable as boolean"));5324 Log(("%s: Bootable=%RTbool\n", __FUNCTION__, fBootable));5325 5095 5326 5096 /* Init static parts. */ … … 5557 5327 ("Failed to attach to status driver. rc=%Rrc\n", rc), 5558 5328 PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic cannot attach to status driver"))); 5559 5560 /* Initialize the SCSI emulation for the BIOS. */5561 rc = vboxscsiInitialize(&pThisCC->VBoxSCSI);5562 if (RT_FAILURE(rc))5563 return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic failed to initialize BIOS SCSI interface"));5564 5565 /*5566 * Register I/O port space in ISA region for BIOS access5567 * if the controller is marked as bootable.5568 */5569 if (fBootable)5570 {5571 if (pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI)5572 rc = PDMDevHlpIoPortCreateExAndMap(pDevIns, LSILOGIC_BIOS_IO_PORT, 4 /*cPorts*/, 0 /*fFlags*/,5573 lsilogicR3IsaIOPortWrite, lsilogicR3IsaIOPortRead,5574 lsilogicR3IsaIOPortWriteStr, lsilogicR3IsaIOPortReadStr, NULL /*pvUser*/,5575 "LsiLogic BIOS", NULL /*paExtDesc*/, &pThis->hIoPortsBios);5576 else if (pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SAS)5577 rc = PDMDevHlpIoPortCreateExAndMap(pDevIns, LSILOGIC_SAS_BIOS_IO_PORT, 4 /*cPorts*/, 0 /*fFlags*/,5578 lsilogicR3IsaIOPortWrite, lsilogicR3IsaIOPortRead,5579 lsilogicR3IsaIOPortWriteStr, lsilogicR3IsaIOPortReadStr, NULL /*pvUser*/,5580 "LsiLogic SAS BIOS", NULL /*paExtDesc*/, &pThis->hIoPortsBios);5581 else5582 AssertMsgFailedReturn(("Invalid controller type %d\n", pThis->enmCtrlType), VERR_INTERNAL_ERROR_3);5583 AssertRCReturn(rc, PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic cannot register legacy I/O handlers")));5584 }5585 5329 5586 5330 /* Register save state handlers. */
Note:
See TracChangeset
for help on using the changeset viewer.