Changeset 83141 in vbox
- Timestamp:
- Feb 24, 2020 5:50:34 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevBusLogic.cpp
r83132 r83141 1034 1034 1035 1035 /** 1036 * Assert IRQ line of the BusLogic adapter. 1036 * Assert IRQ line of the BusLogic adapter. Rather than using 1037 * the more modern method of the guest explicitly only clearing 1038 * the interrupt causes it handled, BusLogic never reports all 1039 * interrupts at once. Instead, new interrupts are postponed if 1040 * an interrupt of a different type is still pending. 1037 1041 * 1038 1042 * @returns nothing. … … 1044 1048 static void buslogicSetInterrupt(PPDMDEVINS pDevIns, PBUSLOGIC pThis, bool fSuppressIrq, uint8_t uIrqType) 1045 1049 { 1046 LogFlowFunc(("pThis=%#p\n", pThis)); 1047 1048 /* The CMDC interrupt has priority over IMBL and OMBR. */ 1049 if (uIrqType & (BL_INTR_IMBL | BL_INTR_OMBR)) 1050 { 1050 LogFlowFunc(("pThis=%#p, setting %#02x (current %#02x, pending %#02x)\n", 1051 pThis, uIrqType, pThis->regInterrupt, pThis->uPendingIntr)); 1052 1053 /* A CMDC interrupt overrides other pending interrupts. The documentation may claim 1054 * otherwise, but a real BT-958 replaces a pending IMBL with a CMDC; the IMBL simply 1055 * vanishes. However, if there's a CMDC already active, another CMDC is latched and 1056 * reported once the first CMDC is cleared. 1057 */ 1058 if (uIrqType & BL_INTR_CMDC) 1059 { 1060 Assert(uIrqType == BL_INTR_CMDC); 1061 if ((pThis->regInterrupt & BL_INTR_INTV) && !(pThis->regInterrupt & BL_INTR_CMDC)) 1062 Log(("CMDC overriding pending interrupt! (was %02x)\n", pThis->regInterrupt)); 1051 1063 if (!(pThis->regInterrupt & BL_INTR_CMDC)) 1052 pThis->regInterrupt |= uIrqType ;/* Report now. */1064 pThis->regInterrupt |= uIrqType | BL_INTR_INTV; /* Report now. */ 1053 1065 else 1054 pThis->uPendingIntr |= uIrqType; /* Report later. */ 1055 } 1056 else if (uIrqType & BL_INTR_CMDC) 1057 { 1058 AssertMsg(pThis->regInterrupt == 0 || pThis->regInterrupt == (BL_INTR_INTV | BL_INTR_CMDC), 1059 ("regInterrupt=%02X\n", pThis->regInterrupt)); 1060 pThis->regInterrupt |= uIrqType; 1061 } 1062 else 1063 AssertMsgFailed(("Invalid interrupt state!\n")); 1064 1065 pThis->regInterrupt |= BL_INTR_INTV; 1066 pThis->uPendingIntr |= uIrqType; /* Report later. */ 1067 } 1068 else if (uIrqType & (BL_INTR_IMBL | BL_INTR_OMBR)) 1069 { 1070 /* If the CMDC interrupt is pending, store IMBL/OMBR for later. Note that IMBL 1071 * and OMBR can be reported together even if an interrupt of the other type is 1072 * already pending. 1073 */ 1074 if (!(pThis->regInterrupt & BL_INTR_CMDC)) 1075 pThis->regInterrupt |= uIrqType | BL_INTR_INTV; /* Report now. */ 1076 else 1077 pThis->uPendingIntr |= uIrqType; /* Report later. */ 1078 } 1079 else /* We do not expect to see BL_INTR_RSTS at this point. */ 1080 AssertMsgFailed(("Invalid interrupt state (unknown interrupt cause)!\n")); 1081 AssertMsg(pThis->regInterrupt, ("Invalid interrupt state (interrupt not set)!\n")); 1082 AssertMsg(pThis->regInterrupt != BL_INTR_INTV, ("Invalid interrupt state (set but no cause)!\n")); 1083 1066 1084 if (pThis->fIRQEnabled && !fSuppressIrq) 1067 1085 { … … 1185 1203 /** 1186 1204 * Resets the command state machine for the next command and notifies the guest. 1205 * Note that suppressing CMDC also suppresses the interrupt, but not vice versa. 1187 1206 * 1188 1207 * @returns nothing. … … 1199 1218 pThis->fUseLocalRam = false; 1200 1219 pThis->regStatus |= BL_STAT_HARDY; 1220 pThis->regStatus &= ~BL_STAT_DIRRDY; 1201 1221 pThis->iReply = 0; 1202 1222 1203 /* The Enable OMBR command doesnot set CMDC when successful. */1223 /* Some commands do not set CMDC when successful. */ 1204 1224 if (!fSuppressCMDC) 1205 1225 { 1206 1226 /* Notify that the command is complete. */ 1207 pThis->regStatus &= ~BL_STAT_DIRRDY;1208 1227 buslogicSetInterrupt(pDevIns, pThis, fSuppressIrq, BL_INTR_CMDC); 1209 1228 } … … 2240 2259 else 2241 2260 pThis->fIRQEnabled = true; 2242 /* No interrupt signaled regardless of enable/disable. */2261 /* No interrupt signaled regardless of enable/disable. NB: CMDC is still signaled! */ 2243 2262 fSuppressIrq = true; 2244 2263 break; … … 2348 2367 pThis->regStatus |= BL_STAT_DIRRDY; 2349 2368 else if (!pThis->cbCommandParametersLeft) 2350 buslogicCommandComplete(pDevIns, pThis, fSuppressIrq, fSuppressCMDC 2369 buslogicCommandComplete(pDevIns, pThis, fSuppressIrq, fSuppressCMDC); 2351 2370 2352 2371 return rc; … … 2418 2437 */ 2419 2438 if (pThis->uOperationCode == BUSLOGICCOMMAND_FETCH_HOST_ADAPTER_LOCAL_RAM) 2420 buslogicCommandComplete(pDevIns, pThis, true /* fSuppressIrq */, true /* fSuppressCMDC */ 2439 buslogicCommandComplete(pDevIns, pThis, true /* fSuppressIrq */, true /* fSuppressCMDC */); 2421 2440 else 2422 2441 buslogicCommandComplete(pDevIns, pThis, false, false);
Note:
See TracChangeset
for help on using the changeset viewer.