Changeset 51232 in vbox for trunk/src/VBox/Devices/Storage
- Timestamp:
- May 12, 2014 10:14:17 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevAHCI.cpp
r51114 r51232 1053 1053 AssertRC(rc); 1054 1054 } 1055 1056 /** 1057 * Finishes the port reset of the given port. 1058 * 1059 * @returns nothing. 1060 * @param pAhciPort The port to finish the reset on. 1061 */ 1062 static void ahciPortResetFinish(PAHCIPort pAhciPort) 1063 { 1064 /* Cancel all tasks first. */ 1065 bool fAllTasksCanceled = ahciCancelActiveTasks(pAhciPort); 1066 Assert(fAllTasksCanceled); 1067 1068 /* Signature for SATA device. */ 1069 if (pAhciPort->fATAPI) 1070 pAhciPort->regSIG = AHCI_PORT_SIG_ATAPI; 1071 else 1072 pAhciPort->regSIG = AHCI_PORT_SIG_DISK; 1073 1074 pAhciPort->regSSTS = (0x01 << 8) | /* Interface is active. */ 1075 (0x03 << 0); /* Device detected and communication established. */ 1076 1077 /* 1078 * Use the maximum allowed speed. 1079 * (Not that it changes anything really) 1080 */ 1081 switch (AHCI_PORT_SCTL_SPD_GET(pAhciPort->regSCTL)) 1082 { 1083 case 0x01: 1084 pAhciPort->regSSTS |= (0x01 << 4); /* Generation 1 (1.5GBps) speed. */ 1085 break; 1086 case 0x02: 1087 case 0x00: 1088 default: 1089 pAhciPort->regSSTS |= (0x02 << 4); /* Generation 2 (3.0GBps) speed. */ 1090 break; 1091 } 1092 1093 /* We received a COMINIT from the device. Tell the guest. */ 1094 ASMAtomicOrU32(&pAhciPort->regIS, AHCI_PORT_IS_PCS); 1095 pAhciPort->regSERR |= AHCI_PORT_SERR_X; 1096 pAhciPort->regTFD |= ATA_STAT_BUSY; 1097 1098 if ((pAhciPort->regCMD & AHCI_PORT_CMD_FRE) && (!pAhciPort->fFirstD2HFisSend)) 1099 { 1100 ahciPostFirstD2HFisIntoMemory(pAhciPort); 1101 ASMAtomicOrU32(&pAhciPort->regIS, AHCI_PORT_IS_DHRS); 1102 1103 if (pAhciPort->regIE & AHCI_PORT_IE_DHRE) 1104 { 1105 int rc = ahciHbaSetInterrupt(pAhciPort->CTX_SUFF(pAhci), pAhciPort->iLUN, VERR_IGNORED); 1106 AssertRC(rc); 1107 } 1108 } 1109 1110 ASMAtomicXchgBool(&pAhciPort->fPortReset, false); 1111 } 1055 1112 #endif 1113 1114 /** 1115 * Kicks the I/O thread from RC or R0. 1116 * 1117 * @returns nothing. 1118 * @param pAhci The AHCI controller instance. 1119 * @param pAhciPort The port to kick. 1120 */ 1121 static void ahciIoThreadKick(PAHCI pAhci, PAHCIPort pAhciPort) 1122 { 1123 #ifdef IN_RC 1124 PDEVPORTNOTIFIERQUEUEITEM pItem = (PDEVPORTNOTIFIERQUEUEITEM)PDMQueueAlloc(pAhci->CTX_SUFF(pNotifierQueue)); 1125 AssertMsg(VALID_PTR(pItem), ("Allocating item for queue failed\n")); 1126 1127 if (pItem) 1128 { 1129 pItem->iPort = pAhciPort->iLUN; 1130 PDMQueueInsert(pAhci->CTX_SUFF(pNotifierQueue), (PPDMQUEUEITEMCORE)pItem); 1131 } 1132 #else 1133 LogFlowFunc(("Signal event semaphore\n")); 1134 int rc = SUPSemEventSignal(pAhci->pSupDrvSession, pAhciPort->hEvtProcess); 1135 AssertRC(rc); 1136 #endif 1137 } 1056 1138 1057 1139 static int PortCmdIssue_w(PAHCI ahci, PAHCIPort pAhciPort, uint32_t iReg, uint32_t u32Value) … … 1076 1158 ASMAtomicOrU32(&pAhciPort->u32TasksNew, u32Value); 1077 1159 1078 /* Send a notification to R3 if u32TasksNew was before our write. */1160 /* Send a notification to R3 if u32TasksNew was 0 before our write. */ 1079 1161 if (ASMAtomicReadBool(&pAhciPort->fWrkThreadSleeping)) 1080 { 1081 #ifdef IN_RC 1082 PDEVPORTNOTIFIERQUEUEITEM pItem = (PDEVPORTNOTIFIERQUEUEITEM)PDMQueueAlloc(ahci->CTX_SUFF(pNotifierQueue)); 1083 AssertMsg(VALID_PTR(pItem), ("Allocating item for queue failed\n")); 1084 1085 pItem->iPort = pAhciPort->iLUN; 1086 PDMQueueInsert(ahci->CTX_SUFF(pNotifierQueue), (PPDMQUEUEITEMCORE)pItem); 1087 #else 1088 LogFlowFunc(("Signal event semaphore\n")); 1089 int rc = SUPSemEventSignal(ahci->pSupDrvSession, pAhciPort->hEvtProcess); 1090 AssertRC(rc); 1091 #endif 1092 } 1162 ahciIoThreadKick(ahci, pAhciPort); 1093 1163 } 1094 1164 … … 1179 1249 pAhciPort->iLUN)); 1180 1250 1181 /* Make sure the async I/O thread is not working before we start to cancel active requests. */1182 while ( pAhciPort->u32TasksNew1183 || !pAhciPort->fWrkThreadSleeping)1184 RTThreadYield();1185 1186 /* Cancel all tasks first. */1187 bool fAllTasksCanceled = ahciCancelActiveTasks(pAhciPort);1188 Assert(fAllTasksCanceled);1189 1190 1251 pAhciPort->regSSTS = 0; 1191 1252 pAhciPort->regSIG = ~0; 1192 1253 pAhciPort->regTFD = 0x7f; 1193 1254 pAhciPort->fFirstD2HFisSend = false; 1255 pAhciPort->regSCTL = u32Value; 1194 1256 } 1195 1257 else if ( (u32Value & AHCI_PORT_SCTL_DET) == AHCI_PORT_SCTL_DET_NINIT … … 1197 1259 && pAhciPort->pDrvBase) 1198 1260 { 1199 if (pAhciPort->pDrvBase) 1200 { 1201 ASMAtomicXchgBool(&pAhciPort->fPortReset, false); 1202 1203 /* Signature for SATA device. */ 1204 if (pAhciPort->fATAPI) 1205 pAhciPort->regSIG = AHCI_PORT_SIG_ATAPI; 1206 else 1207 pAhciPort->regSIG = AHCI_PORT_SIG_DISK; 1208 1209 pAhciPort->regSSTS = (0x01 << 8) | /* Interface is active. */ 1210 (0x03 << 0); /* Device detected and communication established. */ 1211 1212 /* 1213 * Use the maximum allowed speed. 1214 * (Not that it changes anything really) 1215 */ 1216 switch (AHCI_PORT_SCTL_SPD_GET(pAhciPort->regSCTL)) 1217 { 1218 case 0x01: 1219 pAhciPort->regSSTS |= (0x01 << 4); /* Generation 1 (1.5GBps) speed. */ 1220 break; 1221 case 0x02: 1222 case 0x00: 1223 default: 1224 pAhciPort->regSSTS |= (0x02 << 4); /* Generation 2 (3.0GBps) speed. */ 1225 break; 1226 } 1227 1228 /* We received a COMINIT from the device. Tell the guest. */ 1229 ASMAtomicOrU32(&pAhciPort->regIS, AHCI_PORT_IS_PCS); 1230 pAhciPort->regSERR |= AHCI_PORT_SERR_X; 1231 pAhciPort->regTFD |= ATA_STAT_BUSY; 1232 1233 if ((pAhciPort->regCMD & AHCI_PORT_CMD_FRE) && (!pAhciPort->fFirstD2HFisSend)) 1234 { 1235 ahciPostFirstD2HFisIntoMemory(pAhciPort); 1236 ASMAtomicOrU32(&pAhciPort->regIS, AHCI_PORT_IS_DHRS); 1237 1238 if (pAhciPort->regIE & AHCI_PORT_IE_DHRE) 1239 { 1240 int rc = ahciHbaSetInterrupt(pAhciPort->CTX_SUFF(pAhci), pAhciPort->iLUN, VERR_IGNORED); 1241 AssertRC(rc); 1242 } 1243 } 1244 } 1245 } 1246 1247 pAhciPort->regSCTL = u32Value; 1261 pAhciPort->regSCTL = u32Value; /* Update before kicking the I/O thread. */ 1262 pAhciPort->regSSTS = 0x1; /* Indicate device presence detected but communication not established. */ 1263 1264 /* Kick the thread to finish the reset. */ 1265 ahciIoThreadKick(ahci, pAhciPort); 1266 } 1248 1267 1249 1268 return VINF_SUCCESS; … … 5905 5924 ASMAtomicCmpXchgSize(&pAhciReq->enmTxState, AHCITXSTATE_FREE, AHCITXSTATE_ACTIVE, fXchg); 5906 5925 5907 if (fXchg) 5926 if ( fXchg 5927 && !ASMAtomicReadBool(&pAhciPort->fPortReset)) 5908 5928 { 5909 5929 if (pAhciReq->enmTxDir == AHCITXDIR_READ) … … 6020 6040 * The guest might use it for other things now because it doesn't know about that task anymore. 6021 6041 */ 6022 AssertMsg(pAhciReq->enmTxState == AHCITXSTATE_CANCELED, 6042 AssertMsg( pAhciReq->enmTxState == AHCITXSTATE_CANCELED 6043 || pAhciPort->fPortReset, 6023 6044 ("Task is not active but wasn't canceled!\n")); 6024 6045 … … 6736 6757 } /* while tasks available */ 6737 6758 6759 /* Check whether a port reset was active. */ 6760 if ( ASMAtomicReadBool(&pAhciPort->fPortReset) 6761 && (pAhciPort->regSCTL & AHCI_PORT_SCTL_DET) == AHCI_PORT_SCTL_DET_NINIT) 6762 ahciPortResetFinish(pAhciPort); 6763 6738 6764 /* 6739 6765 * Check whether a host controller reset is pending and execute the reset
Note:
See TracChangeset
for help on using the changeset viewer.