Changeset 36800 in vbox
- Timestamp:
- Apr 21, 2011 4:56:28 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 71356
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevAHCI.cpp
r36383 r36800 256 256 257 257 /** 258 * Task state. 259 */ 260 typedef enum AHCITXSTATE 261 { 262 /** Invalid. */ 263 AHCITXSTATE_INVALID = 0, 264 /** Task is not active. */ 265 AHCITXSTATE_FREE, 266 /** Task is active */ 267 AHCITXSTATE_ACTIVE, 268 /** Task was canceled but the request didn't completed yet. */ 269 AHCITXSTATE_CANCELED, 270 /** 32bit hack. */ 271 AHCITXSTATE_32BIT_HACK = 0x7fffffff 272 } AHCITXSTATE, *PAHCITXSTATE; 273 274 /** 258 275 * A task state. 259 276 */ 260 277 typedef struct AHCIPORTTASKSTATE 261 278 { 279 /** Task state. */ 280 volatile AHCITXSTATE enmTxState; 262 281 /** Tag of the task. */ 263 282 uint32_t uTag; … … 307 326 * and the callback copies the data to the destination. */ 308 327 PFNAHCIPOSTPROCESS pfnPostProcess; 309 #ifdef RT_STRICT310 /** Flag whether the task state is currently active - used for debugging */311 volatile bool fActive;312 #endif313 328 } AHCIPORTTASKSTATE; 314 329 … … 884 899 PDMBOTHCBDECL(int) ahciLegacyFakeRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb); 885 900 #ifdef IN_RING3 886 static int ahciPostFisIntoMemory(PAHCIPort pAhciPort, unsigned uFisType, uint8_t *cmdFis);901 static int ahciPostFisIntoMemory(PAHCIPort pAhciPort, unsigned uFisType, uint8_t *cmdFis); 887 902 static void ahciPostFirstD2HFisIntoMemory(PAHCIPort pAhciPort); 888 static int ahciScatterGatherListCopyFromBuffer(PAHCIPORTTASKSTATE pAhciPortTaskState, void *pvBuf, size_t cbBuf); 889 static int ahciScatterGatherListCreate(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState, bool fReadonly); 890 static int ahciScatterGatherListDestroy(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState); 903 static int ahciScatterGatherListCopyFromBuffer(PAHCIPORTTASKSTATE pAhciPortTaskState, void *pvBuf, size_t cbBuf); 904 static int ahciScatterGatherListCreate(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState, bool fReadonly); 905 static void ahciScatterGatherListFree(PAHCIPORTTASKSTATE pAhciPortTaskState); 906 static int ahciScatterGatherListDestroy(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState); 891 907 static void ahciCopyFromBufferIntoSGList(PPDMDEVINS pDevIns, PAHCIPORTTASKSTATESGENTRY pSGInfo); 892 908 static void ahciCopyFromSGListIntoBuffer(PPDMDEVINS pDevIns, PAHCIPORTTASKSTATESGENTRY pSGInfo); 893 909 static void ahciScatterGatherListGetTotalBufferSize(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState); 894 static int ahciScatterGatherListCreateSafe(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState, 895 bool fReadonly, unsigned cSGEntriesProcessed); 910 static int ahciScatterGatherListCreateSafe(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState, 911 bool fReadonly, unsigned cSGEntriesProcessed); 912 static bool ahciCancelActiveTasks(PAHCIPort pAhciPort); 896 913 #endif 897 914 RT_C_DECLS_END … … 1123 1140 AHCI_PORT_SCTL_IPM_GET(u32Value), AHCI_PORT_SCTL_SPD_GET(u32Value), AHCI_PORT_SCTL_DET_GET(u32Value))); 1124 1141 1142 #ifndef IN_RING3 1143 return VINF_IOM_HC_MMIO_WRITE; 1144 #else 1125 1145 if ((u32Value & AHCI_PORT_SCTL_DET) == AHCI_PORT_SCTL_DET_INIT) 1126 1146 { 1147 bool fAllTasksCanceled; 1148 1149 /* Cancel all tasks first. */ 1150 fAllTasksCanceled = ahciCancelActiveTasks(pAhciPort); 1151 Assert(fAllTasksCanceled); 1152 1127 1153 ASMAtomicXchgBool(&pAhciPort->fPortReset, true); 1128 1154 pAhciPort->regSSTS = 0; … … 1134 1160 (pAhciPort->regSCTL & AHCI_PORT_SCTL_DET) == AHCI_PORT_SCTL_DET_INIT) 1135 1161 { 1136 #ifndef IN_RING31137 return VINF_IOM_HC_MMIO_WRITE;1138 #else1139 1162 if (pAhciPort->pDrvBase) 1140 1163 { … … 1183 1206 } 1184 1207 } 1208 } 1209 1210 pAhciPort->regSCTL = u32Value; 1211 1212 return VINF_SUCCESS; 1185 1213 #endif 1186 }1187 1188 pAhciPort->regSCTL = u32Value;1189 1190 return VINF_SUCCESS;1191 1214 } 1192 1215 … … 1675 1698 (u32Value & AHCI_HBA_CTRL_HR))); 1676 1699 1700 #ifndef IN_RING3 1701 return VINF_IOM_HC_MMIO_WRITE; 1702 #else 1677 1703 ahci->regHbaCtrl = (u32Value & AHCI_HBA_CTRL_RW_MASK) | AHCI_HBA_CTRL_AE; 1678 1704 if (ahci->regHbaCtrl & AHCI_HBA_CTRL_HR) 1679 1705 ahciHBAReset(ahci); 1680 1706 return VINF_SUCCESS; 1707 #endif 1681 1708 } 1682 1709 … … 1856 1883 }; 1857 1884 1885 #ifdef IN_RING3 1858 1886 /** 1859 1887 * Reset initiated by system software for one port. … … 1863 1891 static void ahciPortSwReset(PAHCIPort pAhciPort) 1864 1892 { 1893 bool fAllTasksCanceled; 1894 1895 /* Cancel all tasks first. */ 1896 fAllTasksCanceled = ahciCancelActiveTasks(pAhciPort); 1897 Assert(fAllTasksCanceled); 1898 1865 1899 pAhciPort->regIS = 0; 1866 1900 pAhciPort->regIE = 0; … … 1912 1946 } 1913 1947 1914 #ifdef IN_RING31915 1948 /** 1916 1949 * Hardware reset used for machine power on and reset. … … 1930 1963 pAhciPort->GCPhysAddrFb = 0; 1931 1964 } 1932 #endif1933 1965 1934 1966 /** … … 2002 2034 pThis->regHbaCtrl &= ~AHCI_HBA_CTRL_HR; 2003 2035 } 2036 #endif 2004 2037 2005 2038 /** … … 5542 5575 5543 5576 /** 5577 * Free all memory of the scatter gather list. 5578 * 5579 * @returns nothing. 5580 * @param pAhciPortTaskState Task state. 5581 */ 5582 static void ahciScatterGatherListFree(PAHCIPORTTASKSTATE pAhciPortTaskState) 5583 { 5584 if (pAhciPortTaskState->pSGListHead) 5585 RTMemFree(pAhciPortTaskState->pSGListHead); 5586 if (pAhciPortTaskState->paSGEntries) 5587 RTMemFree(pAhciPortTaskState->paSGEntries); 5588 if (pAhciPortTaskState->pvBufferUnaligned) 5589 RTMemPageFree(pAhciPortTaskState->pvBufferUnaligned, pAhciPortTaskState->cbBufferUnaligned); 5590 5591 /* Safety. */ 5592 pAhciPortTaskState->cSGListSize = 0; 5593 pAhciPortTaskState->cSGListTooBig = 0; 5594 pAhciPortTaskState->pSGListHead = NULL; 5595 pAhciPortTaskState->paSGEntries = NULL; 5596 pAhciPortTaskState->pvBufferUnaligned = NULL; 5597 pAhciPortTaskState->cbBufferUnaligned = 0; 5598 } 5599 5600 /** 5544 5601 * Destroy a scatter gather list and free all occupied resources (mappings, etc.) 5545 5602 * … … 5586 5643 /* Free allocated memory if the list was too big too many times. */ 5587 5644 if (pAhciPortTaskState->cSGListTooBig >= AHCI_NR_OF_ALLOWED_BIGGER_LISTS) 5588 { 5589 RTMemFree(pAhciPortTaskState->pSGListHead); 5590 RTMemFree(pAhciPortTaskState->paSGEntries); 5591 if (pAhciPortTaskState->pvBufferUnaligned) 5592 RTMemPageFree(pAhciPortTaskState->pvBufferUnaligned, pAhciPortTaskState->cbBufferUnaligned); 5593 pAhciPortTaskState->cSGListSize = 0; 5594 pAhciPortTaskState->cSGListTooBig = 0; 5595 pAhciPortTaskState->pSGListHead = NULL; 5596 pAhciPortTaskState->paSGEntries = NULL; 5597 pAhciPortTaskState->pvBufferUnaligned = NULL; 5598 pAhciPortTaskState->cbBufferUnaligned = 0; 5599 } 5645 ahciScatterGatherListFree(pAhciPortTaskState); 5600 5646 5601 5647 STAM_PROFILE_STOP(&pAhciPort->StatProfileDestroyScatterGatherList, a); … … 5726 5772 LogFlow(("%s: Copied %d bytes\n", __FUNCTION__, cbCopied)); 5727 5773 return cbCopied; 5774 } 5775 5776 /** 5777 * Cancels all active tasks on the port. 5778 * 5779 * @returns Whether all active tasks were canceled. 5780 * @param pAhciPort The ahci port. 5781 */ 5782 static bool ahciCancelActiveTasks(PAHCIPort pAhciPort) 5783 { 5784 for (unsigned i = 0; i < RT_ELEMENTS(pAhciPort->aCachedTasks); i++) 5785 { 5786 PAHCIPORTTASKSTATE pAhciPortTaskState = pAhciPort->aCachedTasks[i]; 5787 5788 if (VALID_PTR(pAhciPortTaskState)) 5789 { 5790 bool fXchg = false; 5791 ASMAtomicCmpXchgSize(&pAhciPortTaskState->enmTxState, AHCITXSTATE_CANCELED, AHCITXSTATE_ACTIVE, fXchg); 5792 5793 if (fXchg) 5794 { 5795 /* Task is active and was canceled. */ 5796 AssertMsg(pAhciPort->cTasksActive > 0, ("Task was canceled but none is active\n")); 5797 ASMAtomicDecU32(&pAhciPort->cTasksActive); 5798 5799 /* 5800 * Clear the pointer in the cached array. The controller will allocate a 5801 * a new task structure for this tag. 5802 */ 5803 ASMAtomicWriteNullPtr(&pAhciPort->aCachedTasks[i]); 5804 } 5805 else 5806 AssertMsg(pAhciPortTaskState->enmTxState == AHCITXSTATE_FREE, 5807 ("Invalid task state, must be free!\n")); 5808 } 5809 } 5810 5811 return true; /* always true for now because tasks don't use guest memory as the buffer which makes canceling a task impossible. */ 5728 5812 } 5729 5813 … … 5797 5881 static int ahciTransferComplete(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState, int rcReq) 5798 5882 { 5883 bool fXchg = false; 5799 5884 bool fRedo = false; 5800 5885 5801 /* Free system resources occupied by the scatter gather list. */ 5802 if (pAhciPortTaskState->enmTxDir != AHCITXDIR_FLUSH) 5803 ahciScatterGatherListDestroy(pAhciPort, pAhciPortTaskState); 5804 5805 if (pAhciPortTaskState->enmTxDir == AHCITXDIR_READ) 5806 { 5807 STAM_REL_COUNTER_ADD(&pAhciPort->StatBytesRead, pAhciPortTaskState->cbTransfer); 5808 pAhciPort->Led.Actual.s.fReading = 0; 5809 } 5810 else if (pAhciPortTaskState->enmTxDir == AHCITXDIR_WRITE) 5811 { 5812 STAM_REL_COUNTER_ADD(&pAhciPort->StatBytesWritten, pAhciPortTaskState->cbTransfer); 5813 pAhciPort->Led.Actual.s.fWriting = 0; 5814 } 5815 5816 if (RT_FAILURE(rcReq)) 5817 { 5818 /* Log the error. */ 5886 ASMAtomicCmpXchgSize(&pAhciPortTaskState->enmTxState, AHCITXSTATE_FREE, AHCITXSTATE_ACTIVE, fXchg); 5887 5888 if (fXchg) 5889 { 5890 /* Free system resources occupied by the scatter gather list. */ 5891 if (pAhciPortTaskState->enmTxDir != AHCITXDIR_FLUSH) 5892 ahciScatterGatherListDestroy(pAhciPort, pAhciPortTaskState); 5893 5894 if (pAhciPortTaskState->enmTxDir == AHCITXDIR_READ) 5895 { 5896 STAM_REL_COUNTER_ADD(&pAhciPort->StatBytesRead, pAhciPortTaskState->cbTransfer); 5897 pAhciPort->Led.Actual.s.fReading = 0; 5898 } 5899 else if (pAhciPortTaskState->enmTxDir == AHCITXDIR_WRITE) 5900 { 5901 STAM_REL_COUNTER_ADD(&pAhciPort->StatBytesWritten, pAhciPortTaskState->cbTransfer); 5902 pAhciPort->Led.Actual.s.fWriting = 0; 5903 } 5904 5905 if (RT_FAILURE(rcReq)) 5906 { 5907 /* Log the error. */ 5908 if (pAhciPort->cErrors++ < MAX_LOG_REL_ERRORS) 5909 { 5910 if (pAhciPortTaskState->enmTxDir == AHCITXDIR_FLUSH) 5911 LogRel(("AHCI#%u: Flush returned rc=%Rrc\n", 5912 pAhciPort->iLUN, rcReq)); 5913 else 5914 LogRel(("AHCI#%u: %s at offset %llu (%u bytes left) returned rc=%Rrc\n", 5915 pAhciPort->iLUN, 5916 pAhciPortTaskState->enmTxDir == AHCITXDIR_READ 5917 ? "Read" 5918 : "Write", 5919 pAhciPortTaskState->uOffset, 5920 pAhciPortTaskState->cbTransfer, rcReq)); 5921 } 5922 5923 fRedo = ahciIsRedoSetWarning(pAhciPort, rcReq); 5924 if (!fRedo) 5925 { 5926 pAhciPortTaskState->cmdHdr.u32PRDBC = 0; 5927 pAhciPortTaskState->uATARegError = ID_ERR; 5928 pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_ERR; 5929 ASMAtomicCmpXchgPtr(&pAhciPort->pTaskErr, pAhciPortTaskState, NULL); 5930 } 5931 else 5932 ASMAtomicOrU32(&pAhciPort->u32TasksNew, (1 << pAhciPortTaskState->uTag)); 5933 } 5934 else 5935 { 5936 pAhciPortTaskState->cmdHdr.u32PRDBC = pAhciPortTaskState->cbTransfer; 5937 5938 pAhciPortTaskState->uATARegError = 0; 5939 pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_SEEK; 5940 5941 /* Write updated command header into memory of the guest. */ 5942 PDMDevHlpPhysWrite(pAhciPort->CTX_SUFF(pDevIns), pAhciPortTaskState->GCPhysCmdHdrAddr, 5943 &pAhciPortTaskState->cmdHdr, sizeof(CmdHdr)); 5944 } 5945 5946 /* Add the task to the cache. */ 5947 ASMAtomicWritePtr(&pAhciPort->aCachedTasks[pAhciPortTaskState->uTag], pAhciPortTaskState); 5948 ASMAtomicDecU32(&pAhciPort->cTasksActive); 5949 5950 if (!fRedo) 5951 { 5952 if (pAhciPortTaskState->fQueued) 5953 { 5954 if (RT_SUCCESS(rcReq) && !ASMAtomicReadPtrT(&pAhciPort->pTaskErr, PAHCIPORTTASKSTATE)) 5955 ASMAtomicOrU32(&pAhciPort->u32QueuedTasksFinished, (1 << pAhciPortTaskState->uTag)); 5956 5957 /* 5958 * Always raise an interrupt after task completion; delaying 5959 * this (interrupt coalescing) increases latency and has a significant 5960 * impact on performance (see #5071) 5961 */ 5962 ahciSendSDBFis(pAhciPort, 0, true); 5963 } 5964 else 5965 ahciSendD2HFis(pAhciPort, pAhciPortTaskState, pAhciPortTaskState->cmdFis, true); 5966 } 5967 } 5968 else 5969 { 5970 /* 5971 * Task was canceled, do the cleanup but DO NOT access the guest memory! 5972 * The guest might use it for other things now because it doesn't know about that task anymore. 5973 */ 5974 AssertMsg(pAhciPortTaskState->enmTxState == AHCITXSTATE_CANCELED, 5975 ("Task is not active but wasn't canceled!\n")); 5976 5977 ahciScatterGatherListFree(pAhciPortTaskState); 5978 5979 /* Leave a log message about the canceled request. */ 5819 5980 if (pAhciPort->cErrors++ < MAX_LOG_REL_ERRORS) 5820 5981 { 5821 5982 if (pAhciPortTaskState->enmTxDir == AHCITXDIR_FLUSH) 5822 LogRel(("AHCI#%u: Flush returned rc=%Rrc\n",5983 LogRel(("AHCI#%u: Canceled flush returned rc=%Rrc\n", 5823 5984 pAhciPort->iLUN, rcReq)); 5824 5985 else 5825 LogRel(("AHCI#%u: %s at offset %llu (%u bytes left) returned rc=%Rrc\n",5986 LogRel(("AHCI#%u: Canceled %s at offset %llu (%u bytes left) returned rc=%Rrc\n", 5826 5987 pAhciPort->iLUN, 5827 5988 pAhciPortTaskState->enmTxDir == AHCITXDIR_READ 5828 ? " Read"5829 : " Write",5989 ? "read" 5990 : "write", 5830 5991 pAhciPortTaskState->uOffset, 5831 5992 pAhciPortTaskState->cbTransfer, rcReq)); 5832 } 5833 5834 fRedo = ahciIsRedoSetWarning(pAhciPort, rcReq); 5835 if (!fRedo) 5836 { 5837 pAhciPortTaskState->cmdHdr.u32PRDBC = 0; 5838 pAhciPortTaskState->uATARegError = ID_ERR; 5839 pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_ERR; 5840 ASMAtomicCmpXchgPtr(&pAhciPort->pTaskErr, pAhciPortTaskState, NULL); 5841 } 5842 else 5843 ASMAtomicOrU32(&pAhciPort->u32TasksNew, (1 << pAhciPortTaskState->uTag)); 5844 } 5845 else 5846 { 5847 pAhciPortTaskState->cmdHdr.u32PRDBC = pAhciPortTaskState->cbTransfer; 5848 5849 pAhciPortTaskState->uATARegError = 0; 5850 pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_SEEK; 5851 5852 /* Write updated command header into memory of the guest. */ 5853 PDMDevHlpPhysWrite(pAhciPort->CTX_SUFF(pDevIns), pAhciPortTaskState->GCPhysCmdHdrAddr, 5854 &pAhciPortTaskState->cmdHdr, sizeof(CmdHdr)); 5855 } 5856 5857 #ifdef RT_STRICT 5858 bool fXchg = ASMAtomicCmpXchgBool(&pAhciPortTaskState->fActive, false, true); 5859 AssertMsg(fXchg, ("Task is not active\n")); 5860 #endif 5861 5862 /* Add the task to the cache. */ 5863 ASMAtomicWritePtr(&pAhciPort->aCachedTasks[pAhciPortTaskState->uTag], pAhciPortTaskState); 5864 ASMAtomicDecU32(&pAhciPort->cTasksActive); 5865 5866 if (!fRedo) 5867 { 5868 if (pAhciPortTaskState->fQueued) 5869 { 5870 if (RT_SUCCESS(rcReq) && !ASMAtomicReadPtrT(&pAhciPort->pTaskErr, PAHCIPORTTASKSTATE)) 5871 ASMAtomicOrU32(&pAhciPort->u32QueuedTasksFinished, (1 << pAhciPortTaskState->uTag)); 5872 5873 /* 5874 * Always raise an interrupt after task completion; delaying 5875 * this (interrupt coalescing) increases latency and has a significant 5876 * impact on performance (see #5071) 5877 */ 5878 ahciSendSDBFis(pAhciPort, 0, true); 5879 } 5880 else 5881 ahciSendD2HFis(pAhciPort, pAhciPortTaskState, pAhciPortTaskState->cmdFis, true); 5993 } 5994 5995 /* Finally free the task state structure because it is completely unused now. */ 5996 RTMemFree(pAhciPortTaskState); 5882 5997 } 5883 5998 … … 6326 6441 pAhciPortTaskState = (PAHCIPORTTASKSTATE)RTMemAllocZ(sizeof(AHCIPORTTASKSTATE)); 6327 6442 AssertMsg(pAhciPortTaskState, ("%s: Cannot allocate task state memory!\n")); 6443 pAhciPortTaskState->enmTxState = AHCITXSTATE_FREE; 6328 6444 } 6329 6445 else 6330 6446 pAhciPortTaskState = pAhciPort->aCachedTasks[idx]; 6331 6447 6332 #ifdef RT_STRICT 6333 bool fXchg = ASMAtomicCmpXchgBool(&pAhciPortTaskState->fActive, true, false);6448 bool fXchg; 6449 ASMAtomicCmpXchgSize(&pAhciPortTaskState->enmTxState, AHCITXSTATE_ACTIVE, AHCITXSTATE_FREE, fXchg); 6334 6450 AssertMsg(fXchg, ("Task is already active\n")); 6335 #endif6336 6451 6337 6452 pAhciPortTaskState->uATARegStatus = 0; … … 6362 6477 ahciSendD2HFis(pAhciPort, pAhciPortTaskState, pAhciPortTaskState->cmdFis, true); 6363 6478 pAhciPort->aCachedTasks[idx] = pAhciPortTaskState; 6364 #ifdef RT_STRICT 6365 fXchg = ASMAtomicCmpXchgBool(&pAhciPortTaskState->fActive, false, true);6479 6480 ASMAtomicCmpXchgSize(&pAhciPortTaskState->enmTxState, AHCITXSTATE_FREE, AHCITXSTATE_ACTIVE, fXchg); 6366 6481 AssertMsg(fXchg, ("Task is not active\n")); 6367 #endif6368 6482 return true; 6369 6483 } … … 6372 6486 ahciFinishStorageDeviceReset(pAhciPort, pAhciPortTaskState); 6373 6487 pAhciPort->aCachedTasks[idx] = pAhciPortTaskState; 6374 #ifdef RT_STRICT 6375 fXchg = ASMAtomicCmpXchgBool(&pAhciPortTaskState->fActive, false, true);6488 6489 ASMAtomicCmpXchgSize(&pAhciPortTaskState->enmTxState, AHCITXSTATE_FREE, AHCITXSTATE_ACTIVE, fXchg); 6376 6490 AssertMsg(fXchg, ("Task is not active\n")); 6377 #endif6378 6491 return true; 6379 6492 } … … 6428 6541 else 6429 6542 { 6430 #ifdef RT_STRICT 6431 fXchg = ASMAtomicCmpXchgBool(&pAhciPortTaskState->fActive, false, true); 6543 ASMAtomicCmpXchgSize(&pAhciPortTaskState->enmTxState, AHCITXSTATE_FREE, AHCITXSTATE_ACTIVE, fXchg); 6432 6544 AssertMsg(fXchg, ("Task is not active\n")); 6433 #endif6434 6545 6435 6546 /* There is nothing left to do. Notify the guest. */ … … 7383 7494 } 7384 7495 else 7385 { 7386 pAhciPort->cTotalSectors = pAhciPort->pDrvBlock->pfnGetSize(pAhciPort->pDrvBlock) / 512; 7387 7388 /* 7389 * Initialize registers 7390 */ 7391 pAhciPort->regCMD |= AHCI_PORT_CMD_CPS; 7392 ASMAtomicOrU32(&pAhciPort->regIS, AHCI_PORT_IS_CPDS | AHCI_PORT_IS_PRCS); 7393 pAhciPort->regSERR |= AHCI_PORT_SERR_N; 7394 if (pAhciPort->regIE & AHCI_PORT_IE_CPDE) 7395 { 7396 int rc = ahciHbaSetInterrupt(pAhciPort->CTX_SUFF(pAhci), pAhciPort->iLUN, VERR_IGNORED); 7397 AssertRC(rc); 7398 } 7399 } 7496 AssertMsgFailed(("Hard disks don't have a mount interface!\n")); 7400 7497 } 7401 7498 … … 7424 7521 } 7425 7522 else 7426 { 7427 /* 7428 * Inform the guest about the removed device. 7429 */ 7430 pAhciPort->regSSTS = 0; 7431 pAhciPort->regCMD &= ~AHCI_PORT_CMD_CPS; 7432 ASMAtomicOrU32(&pAhciPort->regIS, AHCI_PORT_IS_CPDS | AHCI_PORT_IS_PRCS); 7433 pAhciPort->regSERR |= AHCI_PORT_SERR_N; 7434 if (pAhciPort->regIE & AHCI_PORT_IE_CPDE) 7435 { 7436 int rc = ahciHbaSetInterrupt(pAhciPort->CTX_SUFF(pAhci), pAhciPort->iLUN, VERR_IGNORED); 7437 AssertRC(rc); 7438 } 7439 } 7523 AssertMsgFailed(("Hard disks don't have a mount interface!\n")); 7440 7524 } 7441 7525 … … 8207 8291 if (RT_FAILURE(rc)) 8208 8292 { 8209 8293 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE) 8210 8294 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER, 8211 8295 N_("PIIX3 configuration error: \"ATAPIVendorId\" is longer than 16 bytes")); 8212 8213 8296 return PDMDEV_SET_ERROR(pDevIns, rc, 8297 N_("PIIX3 configuration error: failed to read \"ATAPIVendorId\" as string")); 8214 8298 } 8215 8299 … … 8218 8302 if (RT_FAILURE(rc)) 8219 8303 { 8220 8304 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE) 8221 8305 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER, 8222 8306 N_("PIIX3 configuration error: \"ATAPIProductId\" is longer than 16 bytes")); 8223 8224 8307 return PDMDEV_SET_ERROR(pDevIns, rc, 8308 N_("PIIX3 configuration error: failed to read \"ATAPIProductId\" as string")); 8225 8309 } 8226 8310 … … 8229 8313 if (RT_FAILURE(rc)) 8230 8314 { 8231 8315 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE) 8232 8316 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER, 8233 8317 N_("PIIX3 configuration error: \"ATAPIRevision\" is longer than 4 bytes")); 8234 8235 8318 return PDMDEV_SET_ERROR(pDevIns, rc, 8319 N_("PIIX3 configuration error: failed to read \"ATAPIRevision\" as string")); 8236 8320 } 8237 8321 }
Note:
See TracChangeset
for help on using the changeset viewer.