Changeset 45789 in vbox
- Timestamp:
- Apr 28, 2013 9:26:56 AM (12 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
r45025 r45789 45 45 *******************************************************************************/ 46 46 /** The current saved state version. */ 47 #define LSILOGIC_SAVED_STATE_VERSION 3 47 #define LSILOGIC_SAVED_STATE_VERSION 4 48 /** The saved state version used by VirtualBox before the doorbell status flag 49 * was changed from bool to a 32bit enum. */ 50 #define LSILOGIC_SAVED_STATE_VERSION_BOOL_DOORBELL 3 48 51 /** The saved state version used by VirtualBox before SAS support was added. */ 49 #define LSILOGIC_SAVED_STATE_VERSION_PRE_SAS 252 #define LSILOGIC_SAVED_STATE_VERSION_PRE_SAS 2 50 53 /** The saved state version used by VirtualBox 3.0 and earlier. It does not 51 54 * include the device config part. */ 52 #define LSILOGIC_SAVED_STATE_VERSION_VBOX_30 155 #define LSILOGIC_SAVED_STATE_VERSION_VBOX_30 1 53 56 54 57 /** Maximum number of entries in the release log. */ … … 61 64 * Structures and Typedefs * 62 65 *******************************************************************************/ 66 63 67 /** 64 68 * Reply data. … … 143 147 LSILOGICWHOINIT enmWhoInit; 144 148 /** Flag whether we are in doorbell function. */ 145 bool fDoorbellInProgress;149 LSILOGICDOORBELLSTATE enmDoorbellState; 146 150 /** Flag whether diagnostic access is enabled. */ 147 151 bool fDiagnosticEnabled; 148 149 152 /** Flag whether a notification was send to R3. */ 150 153 bool fNotificationSend; 151 152 154 /** Flag whether the guest enabled event notification from the IOC. */ 153 155 bool fEventNotificationEnabled; 154 155 #if HC_ARCH_BITS == 64156 uint32_t Alignment0;157 #endif158 156 159 157 /** Queue to send tasks to R3. - R3 ptr */ … … 499 497 { 500 498 pThis->enmState = LSILOGICSTATE_RESET; 499 pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_NOT_IN_USE; 501 500 502 501 /* The interrupts are masked out. */ … … 584 583 LogFlowFunc(("pThis=%#p u32MessageContext=%#x\n", pThis, u32MessageContext)); 585 584 586 AssertMsg( !pThis->fDoorbellInProgress, ("We are in a doorbell function\n"));585 AssertMsg(pThis->enmDoorbellState == LSILOGICDOORBELLSTATE_NOT_IN_USE, ("We are in a doorbell function\n")); 587 586 588 587 /* Write message context ID into reply post queue. */ … … 663 662 * we are ready to send the reply. 664 663 */ 665 if (pThis-> fDoorbellInProgress&& !fForceReplyFifo)664 if (pThis->enmDoorbellState != LSILOGICDOORBELLSTATE_NOT_IN_USE && !fForceReplyFifo) 666 665 { 667 666 /* Set size of the reply in 16bit words. The size in the reply is in 32bit dwords. */ … … 732 731 if (fForceReplyFifo) 733 732 { 734 pThis-> fDoorbellInProgress = false;733 pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_NOT_IN_USE; 735 734 lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL); 736 735 } … … 744 743 #endif 745 744 } 745 } 746 747 /** 748 * Returns the number of frames in the reply free queue. 749 * 750 * @returns Number of frames in the reply free queue. 751 * @param pThis Pointer to the LsiLogic device state. 752 */ 753 DECLINLINE(uint32_t) lsilogicReplyFreeQueueGetFrameCount(PLSILOGICSCSI pThis) 754 { 755 uint32_t cReplyFrames = 0; 756 757 if (pThis->uReplyFreeQueueNextAddressRead <= pThis->uReplyFreeQueueNextEntryFreeWrite) 758 cReplyFrames = pThis->uReplyFreeQueueNextEntryFreeWrite - pThis->uReplyFreeQueueNextAddressRead; 759 else 760 cReplyFrames = pThis->cReplyQueueEntries - pThis->uReplyFreeQueueNextAddressRead + pThis->uReplyFreeQueueNextEntryFreeWrite; 761 762 return cReplyFrames; 746 763 } 747 764 … … 1026 1043 * Because the guest is not continuing execution while we are here we can skip this. 1027 1044 */ 1028 if ( !pThis->fDoorbellInProgress)1045 if (pThis->enmDoorbellState == LSILOGICDOORBELLSTATE_NOT_IN_USE) 1029 1046 { 1030 1047 uint32_t uFunction = LSILOGIC_REG_DOORBELL_GET_FUNCTION(u32); … … 1032 1049 switch (uFunction) 1033 1050 { 1051 case LSILOGIC_DOORBELL_FUNCTION_IO_UNIT_RESET: 1034 1052 case LSILOGIC_DOORBELL_FUNCTION_IOC_MSG_UNIT_RESET: 1035 1053 { 1054 /* 1055 * The I/O unit reset does much more on real hardware like 1056 * reloading the firmware, nothing we need to do here, 1057 * so this is like the IOC message unit reset. 1058 */ 1036 1059 pThis->enmState = LSILOGICSTATE_RESET; 1037 1060 … … 1047 1070 pThis->uRequestQueueNextEntryFreeWrite = 0; 1048 1071 pThis->uRequestQueueNextAddressRead = 0; 1049 pThis->enmState = LSILOGICSTATE_READY; 1050 break; 1051 } 1052 case LSILOGIC_DOORBELL_FUNCTION_IO_UNIT_RESET: 1053 { 1054 AssertMsgFailed(("todo\n")); 1072 1073 /* Only the IOC message unit reset transisionts to the ready state. */ 1074 if (uFunction == LSILOGIC_DOORBELL_FUNCTION_IOC_MSG_UNIT_RESET) 1075 pThis->enmState = LSILOGICSTATE_READY; 1055 1076 break; 1056 1077 } … … 1061 1082 AssertMsg(pThis->cMessage <= RT_ELEMENTS(pThis->aMessage), 1062 1083 ("Message doesn't fit into the buffer, cMessage=%u", pThis->cMessage)); 1063 pThis-> fDoorbellInProgress = true;1084 pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_FN_HANDSHAKE; 1064 1085 /* Update the interrupt status to notify the guest that a doorbell function was started. */ 1065 1086 lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL); … … 1068 1089 case LSILOGIC_DOORBELL_FUNCTION_REPLY_FRAME_REMOVAL: 1069 1090 { 1070 AssertMsgFailed(("todo\n")); 1091 pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_RFR_FRAME_COUNT_LOW; 1092 /* Update the interrupt status to notify the guest that a doorbell function was started. */ 1093 lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL); 1071 1094 break; 1072 1095 } … … 1075 1098 } 1076 1099 } 1077 else 1100 else if (pThis->enmDoorbellState == LSILOGICDOORBELLSTATE_FN_HANDSHAKE) 1078 1101 { 1079 1102 /* … … 1117 1140 * is updated afterwards anyway. 1118 1141 */ 1119 if ( (pThis-> fDoorbellInProgress)1142 if ( (pThis->enmDoorbellState == LSILOGICDOORBELLSTATE_FN_HANDSHAKE) 1120 1143 && (pThis->cMessage == pThis->iMessage)) 1121 1144 { … … 1124 1147 /* Reply finished. Reset doorbell in progress status. */ 1125 1148 Log(("%s: Doorbell function finished\n", __FUNCTION__)); 1126 pThis-> fDoorbellInProgress = false;1149 pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_NOT_IN_USE; 1127 1150 } 1151 ASMAtomicOrU32(&pThis->uInterruptStatus, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL); 1152 } 1153 else if ( pThis->enmDoorbellState != LSILOGICDOORBELLSTATE_NOT_IN_USE 1154 && pThis->enmDoorbellState != LSILOGICDOORBELLSTATE_FN_HANDSHAKE) 1155 { 1156 /* Reply frame removal, check whether the reply free queue is empty. */ 1157 if ( pThis->uReplyFreeQueueNextAddressRead == pThis->uReplyFreeQueueNextEntryFreeWrite 1158 && pThis->enmDoorbellState == LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_LOW) 1159 pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_NOT_IN_USE; 1128 1160 ASMAtomicOrU32(&pThis->uInterruptStatus, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL); 1129 1161 } … … 1232 1264 { 1233 1265 u32 = LSILOGIC_REG_DOORBELL_SET_STATE(pThis->enmState); 1234 u32 |= LSILOGIC_REG_DOORBELL_SET_USED(pThis-> fDoorbellInProgress);1266 u32 |= LSILOGIC_REG_DOORBELL_SET_USED(pThis->enmDoorbellState); 1235 1267 u32 |= LSILOGIC_REG_DOORBELL_SET_WHOINIT(pThis->enmWhoInit); 1236 1268 /* … … 1239 1271 * during one read. 1240 1272 */ 1241 if (pThis->fDoorbellInProgress)1273 switch (pThis->enmDoorbellState) 1242 1274 { 1243 /* Return next 16bit value. */ 1244 u32 |= pThis->ReplyBuffer.au16Reply[pThis->uNextReplyEntryRead++]; 1275 case LSILOGICDOORBELLSTATE_NOT_IN_USE: 1276 /* We return the status code of the I/O controller. */ 1277 u32 |= pThis->u16IOCFaultCode; 1278 break; 1279 case LSILOGICDOORBELLSTATE_FN_HANDSHAKE: 1280 /* Return next 16bit value. */ 1281 u32 |= pThis->ReplyBuffer.au16Reply[pThis->uNextReplyEntryRead++]; 1282 lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL); 1283 break; 1284 case LSILOGICDOORBELLSTATE_RFR_FRAME_COUNT_LOW: 1285 { 1286 uint32_t cReplyFrames = lsilogicReplyFreeQueueGetFrameCount(pThis); 1287 1288 u32 |= cReplyFrames & UINT32_C(0xffff); 1289 pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_RFR_FRAME_COUNT_HIGH; 1290 lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL); 1291 break; 1292 } 1293 case LSILOGICDOORBELLSTATE_RFR_FRAME_COUNT_HIGH: 1294 { 1295 uint32_t cReplyFrames = lsilogicReplyFreeQueueGetFrameCount(pThis); 1296 1297 u32 |= cReplyFrames >> 16; 1298 pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_LOW; 1299 lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL); 1300 break; 1301 } 1302 case LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_LOW: 1303 if (pThis->uReplyFreeQueueNextEntryFreeWrite != pThis->uReplyFreeQueueNextAddressRead) 1304 { 1305 u32 |= pThis->CTX_SUFF(pReplyFreeQueueBase)[pThis->uReplyFreeQueueNextAddressRead] & UINT32_C(0xffff); 1306 pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_HIGH; 1307 lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL); 1308 } 1309 break; 1310 case LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_HIGH: 1311 u32 |= pThis->CTX_SUFF(pReplyFreeQueueBase)[pThis->uReplyFreeQueueNextAddressRead] >> 16; 1312 pThis->uReplyFreeQueueNextAddressRead++; 1313 pThis->uReplyFreeQueueNextAddressRead %= pThis->cReplyQueueEntries; 1314 pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_LOW; 1315 lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL); 1316 break; 1317 default: 1318 AssertMsgFailed(("Invalid doorbell state %d\n", pThis->enmDoorbellState)); 1245 1319 } 1246 else 1247 { 1248 /* We return the status code of the I/O controller. */ 1249 u32 |= pThis->u16IOCFaultCode; 1250 } 1320 1251 1321 break; 1252 1322 } … … 2022 2092 if (pTargetDevice->pDrvBase) 2023 2093 { 2024 uint32_t uChainOffset; 2025 2026 /* Create Scatter gather list. */ 2027 uChainOffset = pTaskState->GuestRequest.SCSIIO.u8ChainOffset; 2028 2029 if (uChainOffset) 2030 uChainOffset = uChainOffset * sizeof(uint32_t) - sizeof(MptSCSIIORequest); 2031 2032 rc = lsilogicR3ScatterGatherListCreate(pThis, pTaskState, 2033 pTaskState->GCPhysMessageFrameAddr + sizeof(MptSCSIIORequest), 2034 uChainOffset); 2035 AssertRC(rc); 2094 2095 if (pTaskState->GuestRequest.SCSIIO.u32DataLength) 2096 { 2097 uint32_t uChainOffset; 2098 2099 /* Create Scatter gather list. */ 2100 uChainOffset = pTaskState->GuestRequest.SCSIIO.u8ChainOffset; 2101 2102 if (uChainOffset) 2103 uChainOffset = uChainOffset * sizeof(uint32_t) - sizeof(MptSCSIIORequest); 2104 2105 rc = lsilogicR3ScatterGatherListCreate(pThis, pTaskState, 2106 pTaskState->GCPhysMessageFrameAddr + sizeof(MptSCSIIORequest), 2107 uChainOffset); 2108 AssertRC(rc); 2109 } 2036 2110 2037 2111 # if 0 … … 2134 2208 if (fRedo) 2135 2209 { 2136 if (!pTaskState->fBIOS )2210 if (!pTaskState->fBIOS && pTaskState->PDMScsiRequest.cbScatterGather) 2137 2211 lsilogicR3ScatterGatherListDestroy(pThis, pTaskState); 2138 2212 … … 2171 2245 : pTaskState->PDMScsiRequest.cbSenseBuffer); 2172 2246 # endif 2173 lsilogicR3ScatterGatherListDestroy(pThis, pTaskState); 2247 if (pTaskState->PDMScsiRequest.cbScatterGather) 2248 lsilogicR3ScatterGatherListDestroy(pThis, pTaskState); 2174 2249 2175 2250 … … 3980 4055 pHlp->pfnPrintf(pHlp, "enmState=%u\n", pThis->enmState); 3981 4056 pHlp->pfnPrintf(pHlp, "enmWhoInit=%u\n", pThis->enmWhoInit); 3982 pHlp->pfnPrintf(pHlp, " fDoorbellInProgress=%RTbool\n", pThis->fDoorbellInProgress);4057 pHlp->pfnPrintf(pHlp, "enmDoorbellState=%d\n", pThis->enmDoorbellState); 3983 4058 pHlp->pfnPrintf(pHlp, "fDiagnosticEnabled=%RTbool\n", pThis->fDiagnosticEnabled); 3984 4059 pHlp->pfnPrintf(pHlp, "fNotificationSend=%RTbool\n", pThis->fNotificationSend); … … 4163 4238 SSMR3PutU32 (pSSM, pThis->enmState); 4164 4239 SSMR3PutU32 (pSSM, pThis->enmWhoInit); 4165 SSMR3Put Bool (pSSM, pThis->fDoorbellInProgress);4240 SSMR3PutU32 (pSSM, pThis->enmDoorbellState); 4166 4241 SSMR3PutBool (pSSM, pThis->fDiagnosticEnabled); 4167 4242 SSMR3PutBool (pSSM, pThis->fNotificationSend); … … 4375 4450 SSMR3GetU32 (pSSM, (uint32_t *)&pThis->enmState); 4376 4451 SSMR3GetU32 (pSSM, (uint32_t *)&pThis->enmWhoInit); 4377 SSMR3GetBool (pSSM, &pThis->fDoorbellInProgress); 4452 if (uVersion <= LSILOGIC_SAVED_STATE_VERSION_BOOL_DOORBELL) 4453 { 4454 bool fDoorbellInProgress = false; 4455 4456 /* 4457 * The doorbell status flag distinguishes only between 4458 * doorbell not in use or a Function handshake is currently in progress. 4459 */ 4460 SSMR3GetBool (pSSM, &fDoorbellInProgress); 4461 if (fDoorbellInProgress) 4462 pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_FN_HANDSHAKE; 4463 else 4464 pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_NOT_IN_USE; 4465 } 4466 else 4467 SSMR3GetU32(pSSM, (uint32_t *)&pThis->enmDoorbellState); 4378 4468 SSMR3GetBool (pSSM, &pThis->fDiagnosticEnabled); 4379 4469 SSMR3GetBool (pSSM, &pThis->fNotificationSend); -
trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.h
r44528 r45789 3466 3466 3467 3467 /** 3468 * Doorbell state. 3469 */ 3470 typedef enum LSILOGICDOORBELLSTATE 3471 { 3472 /** Invalid value. */ 3473 LSILOGICDOORBELLSTATE_INVALID = 0, 3474 /** Doorbell not in use. */ 3475 LSILOGICDOORBELLSTATE_NOT_IN_USE, 3476 /** Reply frame removal, transfer number of entries, low 16bits. */ 3477 LSILOGICDOORBELLSTATE_RFR_FRAME_COUNT_LOW, 3478 /** Reply frame removal, transfer number of entries, high 16bits. */ 3479 LSILOGICDOORBELLSTATE_RFR_FRAME_COUNT_HIGH, 3480 /** Reply frame removal, remove next free frame, low part. */ 3481 LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_LOW, 3482 /** Reply frame removal, remove next free frame, high part. */ 3483 LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_HIGH, 3484 /** Function handshake. */ 3485 LSILOGICDOORBELLSTATE_FN_HANDSHAKE, 3486 /** 32bit hack. */ 3487 LSILOGICDOORBELLSTATE_32BIT_HACK = 0x7fffffff 3488 } LSILOGICDOORBELLSTATE; 3489 /** Pointer to a doorbell state. */ 3490 typedef LSILOGICDOORBELLSTATE *PLSILOGICDOORBELLSTATE; 3491 3492 3493 /** 3468 3494 * IOC status codes. 3469 3495 */ … … 3491 3517 #define LSILOGIC_REG_DOORBELL 0x00 3492 3518 # define LSILOGIC_REG_DOORBELL_SET_STATE(enmState) (((enmState) & 0x0f) << 28) 3493 # define LSILOGIC_REG_DOORBELL_SET_USED( fUsed) (((fUsed) ? 1 : 0) << 27)3519 # define LSILOGIC_REG_DOORBELL_SET_USED(enmDoorbell) (((enmDoorbell != LSILOGICDOORBELLSTATE_NOT_IN_USE) ? 1 : 0) << 27) 3494 3520 # define LSILOGIC_REG_DOORBELL_SET_WHOINIT(enmWhoInit) (((enmWhoInit) & 0x07) << 24) 3495 3521 # define LSILOGIC_REG_DOORBELL_SET_FAULT_CODE(u16Code) (u16Code) -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
r45646 r45789 1560 1560 GEN_CHECK_OFF(LSILOGICSCSI, enmState); 1561 1561 GEN_CHECK_OFF(LSILOGICSCSI, enmWhoInit); 1562 GEN_CHECK_OFF(LSILOGICSCSI, fDoorbellInProgress);1562 GEN_CHECK_OFF(LSILOGICSCSI, enmDoorbellState); 1563 1563 GEN_CHECK_OFF(LSILOGICSCSI, fDiagnosticEnabled); 1564 1564 GEN_CHECK_OFF(LSILOGICSCSI, fNotificationSend);
Note:
See TracChangeset
for help on using the changeset viewer.