Changeset 32944 in vbox
- Timestamp:
- Oct 6, 2010 1:46:06 PM (14 years ago)
- File:
-
- 1 edited
-
trunk/src/VBox/Devices/Storage/ATAController.cpp (modified) (27 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/ATAController.cpp
r30723 r32944 7 7 8 8 /* 9 * Copyright (C) 2006-20 09Oracle Corporation9 * Copyright (C) 2006-2010 Oracle Corporation 10 10 * 11 11 * This file is part of VirtualBox Open Source Edition (OSE), as … … 308 308 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT); 309 309 AssertRC(rc); 310 LogRel(("A TA: Ctl: request queue dump (topmost is current):\n"));310 LogRel(("AHCI ATA: Ctl: request queue dump (topmost is current):\n")); 311 311 curr = pCtl->AsyncIOReqTail; 312 312 do 313 313 { 314 314 if (curr == pCtl->AsyncIOReqHead) 315 LogRel(("A TA: Ctl: processed requests (topmost is oldest):\n"));315 LogRel(("AHCI ATA: Ctl: processed requests (topmost is oldest):\n")); 316 316 switch (pCtl->aAsyncIORequests[curr].ReqType) 317 317 { … … 963 963 964 964 965 static int ataReadSectors(AHCIATADevState *s, uint64_t u64Sector, void *pvBuf, uint32_t cSectors) 965 static void ataWarningDiskFull(PPDMDEVINS pDevIns) 966 { 967 int rc; 968 LogRel(("AHCI ATA: Host disk full\n")); 969 rc = PDMDevHlpVMSetRuntimeError(pDevIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DevATA_DISKFULL", 970 N_("Host system reported disk full. VM execution is suspended. You can resume after freeing some space")); 971 AssertRC(rc); 972 } 973 974 static void ataWarningFileTooBig(PPDMDEVINS pDevIns) 975 { 976 int rc; 977 LogRel(("AHCI ATA: File too big\n")); 978 rc = PDMDevHlpVMSetRuntimeError(pDevIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DevATA_FILETOOBIG", 979 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")); 980 AssertRC(rc); 981 } 982 983 static void ataWarningISCSI(PPDMDEVINS pDevIns) 984 { 985 int rc; 986 LogRel(("AHCI ATA: iSCSI target unavailable\n")); 987 rc = PDMDevHlpVMSetRuntimeError(pDevIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DevATA_ISCSIDOWN", 988 N_("The iSCSI target has stopped responding. VM execution is suspended. You can resume when it is available again")); 989 AssertRC(rc); 990 } 991 992 static bool ataIsRedoSetWarning(AHCIATADevState *s, int rc) 993 { 994 PAHCIATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s); 995 Assert(!PDMCritSectIsOwner(&pCtl->lock)); 996 if (rc == VERR_DISK_FULL) 997 { 998 pCtl->fRedoIdle = true; 999 ataWarningDiskFull(ATADEVSTATE_2_DEVINS(s)); 1000 return true; 1001 } 1002 if (rc == VERR_FILE_TOO_BIG) 1003 { 1004 pCtl->fRedoIdle = true; 1005 ataWarningFileTooBig(ATADEVSTATE_2_DEVINS(s)); 1006 return true; 1007 } 1008 if (rc == VERR_BROKEN_PIPE || rc == VERR_NET_CONNECTION_REFUSED) 1009 { 1010 pCtl->fRedoIdle = true; 1011 /* iSCSI connection abort (first error) or failure to reestablish 1012 * connection (second error). Pause VM. On resume we'll retry. */ 1013 ataWarningISCSI(ATADEVSTATE_2_DEVINS(s)); 1014 return true; 1015 } 1016 return false; 1017 } 1018 1019 1020 static int ataReadSectors(AHCIATADevState *s, uint64_t u64Sector, void *pvBuf, 1021 uint32_t cSectors, bool *pfRedo) 966 1022 { 967 1023 PAHCIATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s); … … 978 1034 STAM_REL_COUNTER_ADD(s->pStatBytesRead, cSectors * 512); 979 1035 1036 if (RT_SUCCESS(rc)) 1037 *pfRedo = false; 1038 else 1039 *pfRedo = ataIsRedoSetWarning(s, rc); 1040 980 1041 STAM_PROFILE_START(&pCtl->StatLockWait, a); 981 1042 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS); … … 985 1046 986 1047 987 static int ataWriteSectors(AHCIATADevState *s, uint64_t u64Sector, const void *pvBuf, uint32_t cSectors) 1048 static int ataWriteSectors(AHCIATADevState *s, uint64_t u64Sector, 1049 const void *pvBuf, uint32_t cSectors, bool *pfRedo) 988 1050 { 989 1051 PAHCIATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s); … … 999 1061 1000 1062 STAM_REL_COUNTER_ADD(s->pStatBytesWritten, cSectors * 512); 1063 1064 if (RT_SUCCESS(rc)) 1065 *pfRedo = false; 1066 else 1067 *pfRedo = ataIsRedoSetWarning(s, rc); 1001 1068 1002 1069 STAM_PROFILE_START(&pCtl->StatLockWait, a); … … 1021 1088 1022 1089 1023 static void ataWarningDiskFull(PPDMDEVINS pDevIns)1024 {1025 int rc;1026 LogRel(("ATA: Host disk full\n"));1027 rc = PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "DevATA_DISKFULL",1028 N_("Host system reported disk full. VM execution is suspended. You can resume after freeing some space"));1029 AssertRC(rc);1030 }1031 1032 1033 static void ataWarningFileTooBig(PPDMDEVINS pDevIns)1034 {1035 int rc;1036 LogRel(("ATA: File too big\n"));1037 rc = PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "DevATA_FILETOOBIG",1038 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"));1039 AssertRC(rc);1040 }1041 1042 1043 static void ataWarningISCSI(PPDMDEVINS pDevIns)1044 {1045 int rc;1046 LogRel(("ATA: iSCSI target unavailable\n"));1047 rc = PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "DevATA_ISCSIDOWN",1048 N_("The iSCSI target has stopped responding. VM execution is suspended. You can resume when it is available again"));1049 AssertRC(rc);1050 }1051 1052 1053 1090 static bool ataReadSectorsSS(AHCIATADevState *s) 1054 1091 { … … 1056 1093 uint32_t cSectors; 1057 1094 uint64_t iLBA; 1095 bool fRedo; 1058 1096 1059 1097 cSectors = s->cbElementaryTransfer / 512; … … 1061 1099 iLBA = ataGetSector(s); 1062 1100 Log(("%s: %d sectors at LBA %d\n", __FUNCTION__, cSectors, iLBA)); 1063 rc = ataReadSectors(s, iLBA, s->CTXALLSUFF(pbIOBuffer), cSectors );1101 rc = ataReadSectors(s, iLBA, s->CTXALLSUFF(pbIOBuffer), cSectors, &fRedo); 1064 1102 if (RT_SUCCESS(rc)) 1065 1103 { … … 1071 1109 else 1072 1110 { 1073 if (rc == VERR_DISK_FULL) 1074 { 1075 ataWarningDiskFull(ATADEVSTATE_2_DEVINS(s)); 1111 if (fRedo) 1076 1112 return true; 1077 }1078 if (rc == VERR_FILE_TOO_BIG)1079 {1080 ataWarningFileTooBig(ATADEVSTATE_2_DEVINS(s));1081 return true;1082 }1083 if (rc == VERR_BROKEN_PIPE || rc == VERR_NET_CONNECTION_REFUSED)1084 {1085 /* iSCSI connection abort (first error) or failure to reestablish1086 * connection (second error). Pause VM. On resume we'll retry. */1087 ataWarningISCSI(ATADEVSTATE_2_DEVINS(s));1088 return true;1089 }1090 1113 if (s->cErrors++ < MAX_LOG_REL_ERRORS) 1091 1114 LogRel(("AHCI ATA: LUN#%d: disk read error (rc=%Rrc iSector=%#RX64 cSectors=%#RX32)\n", … … 1093 1116 ataCmdError(s, ID_ERR); 1094 1117 } 1095 /** @todo implement redo for iSCSI */1096 1118 return false; 1097 1119 } … … 1103 1125 uint32_t cSectors; 1104 1126 uint64_t iLBA; 1127 bool fRedo; 1105 1128 1106 1129 cSectors = s->cbElementaryTransfer / 512; … … 1108 1131 iLBA = ataGetSector(s); 1109 1132 Log(("%s: %d sectors at LBA %d\n", __FUNCTION__, cSectors, iLBA)); 1110 rc = ataWriteSectors(s, iLBA, s->CTXALLSUFF(pbIOBuffer), cSectors );1133 rc = ataWriteSectors(s, iLBA, s->CTXALLSUFF(pbIOBuffer), cSectors, &fRedo); 1111 1134 if (RT_SUCCESS(rc)) 1112 1135 { … … 1118 1141 else 1119 1142 { 1120 if (rc == VERR_DISK_FULL) 1121 { 1122 ataWarningDiskFull(ATADEVSTATE_2_DEVINS(s)); 1143 if (fRedo) 1123 1144 return true; 1124 }1125 if (rc == VERR_FILE_TOO_BIG)1126 {1127 ataWarningFileTooBig(ATADEVSTATE_2_DEVINS(s));1128 return true;1129 }1130 if (rc == VERR_BROKEN_PIPE || rc == VERR_NET_CONNECTION_REFUSED)1131 {1132 /* iSCSI connection abort (first error) or failure to reestablish1133 * connection (second error). Pause VM. On resume we'll retry. */1134 ataWarningISCSI(ATADEVSTATE_2_DEVINS(s));1135 return true;1136 }1137 1145 if (s->cErrors++ < MAX_LOG_REL_ERRORS) 1138 1146 LogRel(("AHCI ATA: LUN#%d: disk write error (rc=%Rrc iSector=%#RX64 cSectors=%#RX32)\n", … … 1140 1148 ataCmdError(s, ID_ERR); 1141 1149 } 1142 /** @todo implement redo for iSCSI */1143 1150 return false; 1144 1151 } … … 2767 2774 return; 2768 2775 2769 LogRel(("A TA: LUN#%d: CD/DVD, total number of sectors %Ld, passthrough unchanged\n", pIf->iLUN, pIf->cTotalSectors));2776 LogRel(("AHCI ATA: LUN#%d: CD/DVD, total number of sectors %Ld, passthrough unchanged\n", pIf->iLUN, pIf->cTotalSectors)); 2770 2777 2771 2778 if (pIf->fATAPI) … … 3405 3412 if (pCtl->aIfs[1].u64CmdTS) 3406 3413 uCmdWait1 = (uNow - pCtl->aIfs[1].u64CmdTS) / 1000; 3407 LogRel(("A TA: Ctl: RESET, DevSel=%d AIOIf=%d CmdIf0=%#04x (%d usec ago) CmdIf1=%#04x (%d usec ago)\n",3414 LogRel(("AHCI ATA: Ctl: RESET, DevSel=%d AIOIf=%d CmdIf0=%#04x (%d usec ago) CmdIf1=%#04x (%d usec ago)\n", 3408 3415 pCtl->iSelectedIf, pCtl->iAIOIf, 3409 3416 pCtl->aIfs[0].uATARegCommand, uCmdWait0, … … 3823 3830 if (!(pCtl->BmDma.u8Cmd & BM_CMD_START) || pCtl->fReset) 3824 3831 { 3825 LogRel(("A TA: Ctl: ABORT DMA%s\n", pCtl->fReset ? " due to RESET" : ""));3832 LogRel(("AHCI ATA: Ctl: ABORT DMA%s\n", pCtl->fReset ? " due to RESET" : "")); 3826 3833 if (!pCtl->fReset) 3827 3834 ataDMATransferStop(s); … … 3848 3855 s->iIOBufferCur = iIOBufferCur; 3849 3856 s->iIOBufferEnd = iIOBufferEnd; 3850 }3851 3852 3853 /**3854 * Suspend I/O operations on a controller. Also suspends EMT, because it's3855 * waiting for I/O to make progress. The next attempt to perform an I/O3856 * operation will be made when EMT is resumed up again (as the resume3857 * callback below restarts I/O).3858 *3859 * @param pCtl Controller for which to suspend I/O.3860 */3861 static void ataSuspendRedo(PAHCIATACONTROLLER pCtl)3862 {3863 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);3864 int rc;3865 3866 pCtl->fRedoIdle = true;3867 rc = VMR3ReqCallWait(PDMDevHlpGetVM(pDevIns), VMCPUID_ANY,3868 (PFNRT)PDMDevHlpVMSuspend, 1, pDevIns);3869 AssertReleaseRC(rc);3870 3857 } 3871 3858 … … 4036 4023 LogRel(("%s: Ctl: redo entire operation\n", __FUNCTION__)); 4037 4024 ataAsyncIOPutRequest(pCtl, pReq); 4038 ataSuspendRedo(pCtl);4039 4025 break; 4040 4026 } … … 4139 4125 if (RT_UNLIKELY(pCtl->fRedo)) 4140 4126 { 4141 LogRel(("A TA: Ctl: redo DMA operation\n"));4127 LogRel(("AHCI ATA: Ctl: redo DMA operation\n")); 4142 4128 ataAsyncIOPutRequest(pCtl, &ataDMARequest); 4143 ataSuspendRedo(pCtl);4144 4129 break; 4145 4130 } … … 4185 4170 if (RT_UNLIKELY(fRedo)) 4186 4171 { 4187 LogRel(("A TA: Ctl#%d: redo PIO operation\n"));4172 LogRel(("AHCI ATA: Ctl#%d: redo PIO operation\n")); 4188 4173 ataAsyncIOPutRequest(pCtl, &ataPIORequest); 4189 ataSuspendRedo(pCtl);4190 4174 break; 4191 4175 } … … 4258 4242 pCtl->uAsyncIOState = AHCIATA_AIO_NEW; 4259 4243 pCtl->fReset = false; 4260 LogRel(("A TA: Ctl: finished processing RESET\n"));4244 LogRel(("AHCI ATA: Ctl: finished processing RESET\n")); 4261 4245 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++) 4262 4246 { … … 4868 4852 4869 4853 if (!fAllIdle) 4870 LogRel(("A TA: Ctl is still executing, DevSel=%d AIOIf=%d CmdIf0=%#04x CmdIf1=%#04x\n",4854 LogRel(("AHCI ATA: Ctl is still executing, DevSel=%d AIOIf=%d CmdIf0=%#04x CmdIf1=%#04x\n", 4871 4855 pCtl->iSelectedIf, pCtl->iAIOIf, 4872 4856 pCtl->aIfs[0].uATARegCommand, pCtl->aIfs[1].uATARegCommand)); … … 4921 4905 ASMAtomicWriteU32(&pCtl->fShutdown, true); 4922 4906 rc = RTSemEventSignal(pCtl->AsyncIOSem); 4907 AssertRC(rc); 4908 rc = RTSemEventSignal(pCtl->SuspendIOSem); 4923 4909 AssertRC(rc); 4924 4910 … … 5083 5069 pIf->PCHSGeometry.cHeads = 0; /* dummy */ 5084 5070 pIf->PCHSGeometry.cSectors = 0; /* dummy */ 5085 LogRel(("A TA: LUN#%d: CD/DVD, total number of sectors %Ld, passthrough %s\n", pIf->iLUN, pIf->cTotalSectors, (pIf->fATAPIPassthrough ? "enabled" : "disabled")));5071 LogRel(("AHCI ATA: LUN#%d: CD/DVD, total number of sectors %Ld, passthrough %s\n", pIf->iLUN, pIf->cTotalSectors, (pIf->fATAPIPassthrough ? "enabled" : "disabled"))); 5086 5072 } 5087 5073 else … … 5403 5389 else 5404 5390 { 5405 LogRel(("A TA: No buffer for %d\n", j));5391 LogRel(("AHCI ATA: No buffer for %d\n", j)); 5406 5392 if (SSMR3HandleGetAfter(pSSM) != SSMAFTER_DEBUG_IT) 5407 5393 return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("No buffer for %d"), j);
Note:
See TracChangeset
for help on using the changeset viewer.

