Changeset 39579 in vbox
- Timestamp:
- Dec 11, 2011 9:43:40 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 75339
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevAHCI.cpp
r39136 r39579 6843 6843 } 6844 6844 6845 if ( enmTxDir == AHCITXDIR_FLUSH)6845 if (pAhciPortTaskState->cbSGBuffers < pAhciPortTaskState->cbTransfer) 6846 6846 { 6847 rc = pAhciPort->pDrvBlockAsync->pfnStartFlush(pAhciPort->pDrvBlockAsync, 6848 pAhciPortTaskState); 6849 } 6850 else if (enmTxDir == AHCITXDIR_TRIM) 6851 { 6852 rc = ahciTrimRangesCreate(pAhciPort, pAhciPortTaskState); 6853 if (RT_SUCCESS(rc)) 6854 { 6855 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1; 6856 rc = pAhciPort->pDrvBlockAsync->pfnStartDiscard(pAhciPort->pDrvBlockAsync, pAhciPortTaskState->paRanges, 6857 pAhciPortTaskState->cRanges, pAhciPortTaskState); 6858 } 6859 } 6860 else if (enmTxDir == AHCITXDIR_READ) 6861 { 6862 pAhciPort->Led.Asserted.s.fReading = pAhciPort->Led.Actual.s.fReading = 1; 6863 rc = pAhciPort->pDrvBlockAsync->pfnStartRead(pAhciPort->pDrvBlockAsync, pAhciPortTaskState->uOffset, 6864 pAhciPortTaskState->pSGListHead, pAhciPortTaskState->cSGListUsed, 6865 pAhciPortTaskState->cbTransfer, 6866 pAhciPortTaskState); 6847 /* 6848 * The guest tried to transfer more data than there is space in the buffer. 6849 * Terminate task and set the overflow bit. 6850 */ 6851 ASMAtomicCmpXchgSize(&pAhciPortTaskState->enmTxState, AHCITXSTATE_FREE, AHCITXSTATE_ACTIVE, fXchg); 6852 AssertMsg(fXchg, ("Task is not active\n")); 6853 6854 /* Add the task to the cache. */ 6855 pAhciPort->aCachedTasks[pAhciPortTaskState->uTag] = pAhciPortTaskState; 6856 6857 /* Notify the guest. */ 6858 ASMAtomicOrU32(&pAhciPort->regIS, AHCI_PORT_IS_OFS); 6859 if (pAhciPort->regIE & AHCI_PORT_IE_OFE) 6860 ahciHbaSetInterrupt(pAhciPort->CTX_SUFF(pAhci), pAhciPort->iLUN, VERR_IGNORED); 6867 6861 } 6868 6862 else 6869 6863 { 6870 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1; 6871 rc = pAhciPort->pDrvBlockAsync->pfnStartWrite(pAhciPort->pDrvBlockAsync, pAhciPortTaskState->uOffset, 6872 pAhciPortTaskState->pSGListHead, pAhciPortTaskState->cSGListUsed, 6873 pAhciPortTaskState->cbTransfer, 6874 pAhciPortTaskState); 6864 if (enmTxDir == AHCITXDIR_FLUSH) 6865 { 6866 rc = pAhciPort->pDrvBlockAsync->pfnStartFlush(pAhciPort->pDrvBlockAsync, 6867 pAhciPortTaskState); 6868 } 6869 else if (enmTxDir == AHCITXDIR_TRIM) 6870 { 6871 rc = ahciTrimRangesCreate(pAhciPort, pAhciPortTaskState); 6872 if (RT_SUCCESS(rc)) 6873 { 6874 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1; 6875 rc = pAhciPort->pDrvBlockAsync->pfnStartDiscard(pAhciPort->pDrvBlockAsync, pAhciPortTaskState->paRanges, 6876 pAhciPortTaskState->cRanges, pAhciPortTaskState); 6877 } 6878 } 6879 else if (enmTxDir == AHCITXDIR_READ) 6880 { 6881 pAhciPort->Led.Asserted.s.fReading = pAhciPort->Led.Actual.s.fReading = 1; 6882 rc = pAhciPort->pDrvBlockAsync->pfnStartRead(pAhciPort->pDrvBlockAsync, pAhciPortTaskState->uOffset, 6883 pAhciPortTaskState->pSGListHead, pAhciPortTaskState->cSGListUsed, 6884 pAhciPortTaskState->cbTransfer, 6885 pAhciPortTaskState); 6886 } 6887 else 6888 { 6889 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1; 6890 rc = pAhciPort->pDrvBlockAsync->pfnStartWrite(pAhciPort->pDrvBlockAsync, pAhciPortTaskState->uOffset, 6891 pAhciPortTaskState->pSGListHead, pAhciPortTaskState->cSGListUsed, 6892 pAhciPortTaskState->cbTransfer, 6893 pAhciPortTaskState); 6894 } 6895 if (rc == VINF_VD_ASYNC_IO_FINISHED) 6896 rc = ahciTransferComplete(pAhciPort, pAhciPortTaskState, VINF_SUCCESS); 6897 else if (RT_FAILURE(rc) && rc != VERR_VD_ASYNC_IO_IN_PROGRESS) 6898 rc = ahciTransferComplete(pAhciPort, pAhciPortTaskState, rc); 6875 6899 } 6876 if (rc == VINF_VD_ASYNC_IO_FINISHED)6877 rc = ahciTransferComplete(pAhciPort, pAhciPortTaskState, VINF_SUCCESS);6878 else if (RT_FAILURE(rc) && rc != VERR_VD_ASYNC_IO_IN_PROGRESS)6879 rc = ahciTransferComplete(pAhciPort, pAhciPortTaskState, rc);6880 6900 } 6881 6901 else … … 7110 7130 else if (enmTxDir != AHCITXDIR_NONE) 7111 7131 { 7112 uint64_t uOffset ;7113 size_t cbTransfer ;7132 uint64_t uOffset = 0; 7133 size_t cbTransfer = 0; 7114 7134 PRTSGSEG pSegCurr; 7115 7135 PAHCIPORTTASKSTATESGENTRY pSGInfoCurr; … … 7119 7139 AssertMsgFailed(("%s: Failed to get number of list elments %Rrc\n", __FUNCTION__, rc)); 7120 7140 7121 STAM_REL_COUNTER_INC(&pAhciPort->StatDMA); 7122 7123 /* Initialize all values. */ 7124 uOffset = pAhciPortTaskState->uOffset; 7125 cbTransfer = pAhciPortTaskState->cbTransfer; 7126 pSegCurr = &pAhciPortTaskState->pSGListHead[0]; 7127 pSGInfoCurr = pAhciPortTaskState->paSGEntries; 7128 7129 STAM_PROFILE_START(&pAhciPort->StatProfileReadWrite, b); 7130 7131 while (cbTransfer) 7141 if (pAhciPortTaskState->cbSGBuffers < pAhciPortTaskState->cbTransfer) 7132 7142 { 7133 size_t cbProcess = (cbTransfer < pSegCurr->cbSeg) ? cbTransfer : pSegCurr->cbSeg; 7134 7135 AssertMsg(!(pSegCurr->cbSeg % 512), ("Buffer is not sector aligned cbSeg=%d\n", pSegCurr->cbSeg)); 7136 AssertMsg(!(uOffset % 512), ("Offset is not sector aligned %llu\n", uOffset)); 7137 AssertMsg(!(cbProcess % 512), ("Number of bytes to process is not sector aligned %lu\n", cbProcess)); 7138 7139 if (enmTxDir == AHCITXDIR_READ) 7143 /* 7144 * The guest tried to transfer more data than there is space in the buffer. 7145 * Terminate task and set the overflow bit. 7146 */ 7147 int rc2 = ahciScatterGatherListDestroy(pAhciPort, pAhciPortTaskState); 7148 AssertMsgRC(rc2, ("Destroying task list failed rc=%Rrc\n", rc2)); 7149 7150 /* Notify the guest. */ 7151 ASMAtomicOrU32(&pAhciPort->regIS, AHCI_PORT_IS_OFS); 7152 if (pAhciPort->regIE & AHCI_PORT_IE_OFE) 7153 ahciHbaSetInterrupt(pAhciPort->CTX_SUFF(pAhci), pAhciPort->iLUN, VERR_IGNORED); 7154 } 7155 else 7156 { 7157 STAM_REL_COUNTER_INC(&pAhciPort->StatDMA); 7158 7159 /* Initialize all values. */ 7160 uOffset = pAhciPortTaskState->uOffset; 7161 cbTransfer = pAhciPortTaskState->cbTransfer; 7162 pSegCurr = &pAhciPortTaskState->pSGListHead[0]; 7163 pSGInfoCurr = pAhciPortTaskState->paSGEntries; 7164 7165 STAM_PROFILE_START(&pAhciPort->StatProfileReadWrite, b); 7166 7167 while (cbTransfer) 7140 7168 { 7141 pAhciPort->Led.Asserted.s.fReading = pAhciPort->Led.Actual.s.fReading = 1; 7142 rc = pAhciPort->pDrvBlock->pfnRead(pAhciPort->pDrvBlock, uOffset, 7143 pSegCurr->pvSeg, cbProcess); 7144 pAhciPort->Led.Actual.s.fReading = 0; 7145 if (RT_FAILURE(rc)) 7146 break; 7147 7148 STAM_REL_COUNTER_ADD(&pAhciPort->StatBytesRead, cbProcess); 7149 } 7150 else 7151 { 7152 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1; 7153 rc = pAhciPort->pDrvBlock->pfnWrite(pAhciPort->pDrvBlock, uOffset, 7154 pSegCurr->pvSeg, cbProcess); 7155 pAhciPort->Led.Actual.s.fWriting = 0; 7156 if (RT_FAILURE(rc)) 7157 break; 7158 7159 STAM_REL_COUNTER_ADD(&pAhciPort->StatBytesWritten, cbProcess); 7160 } 7161 7162 /* Go to the next entry. */ 7163 uOffset += cbProcess; 7164 cbTransfer -= cbProcess; 7165 pSegCurr++; 7166 pSGInfoCurr++; 7167 } 7168 7169 STAM_PROFILE_STOP(&pAhciPort->StatProfileReadWrite, b); 7170 7171 /* Log the error. */ 7172 if ( RT_FAILURE(rc) 7173 && pAhciPort->cErrors++ < MAX_LOG_REL_ERRORS) 7174 { 7175 LogRel(("AHCI#%u: %s at offset %llu (%u bytes left) returned rc=%Rrc\n", 7176 pAhciPort->iLUN, 7177 enmTxDir == AHCITXDIR_READ 7178 ? "Read" 7179 : "Write", 7180 uOffset, cbTransfer, rc)); 7181 } 7182 7183 /* Cleanup. */ 7184 int rc2 = ahciScatterGatherListDestroy(pAhciPort, pAhciPortTaskState); 7185 if (RT_FAILURE(rc2)) 7186 AssertMsgFailed(("Destroying task list failed rc=%Rrc\n", rc)); 7187 7188 if (RT_LIKELY(!pAhciPort->fPortReset)) 7189 { 7190 pAhciPortTaskState->cmdHdr.u32PRDBC = pAhciPortTaskState->cbTransfer - cbTransfer; 7191 if (RT_FAILURE(rc)) 7192 { 7193 if (!ahciIsRedoSetWarning(pAhciPort, rc)) 7169 size_t cbProcess = (cbTransfer < pSegCurr->cbSeg) ? cbTransfer : pSegCurr->cbSeg; 7170 7171 AssertMsg(!(pSegCurr->cbSeg % 512), ("Buffer is not sector aligned cbSeg=%d\n", pSegCurr->cbSeg)); 7172 AssertMsg(!(uOffset % 512), ("Offset is not sector aligned %llu\n", uOffset)); 7173 AssertMsg(!(cbProcess % 512), ("Number of bytes to process is not sector aligned %lu\n", cbProcess)); 7174 7175 if (enmTxDir == AHCITXDIR_READ) 7194 7176 { 7195 pAhciPortTaskState->uATARegError = ID_ERR; 7196 pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_ERR; 7177 pAhciPort->Led.Asserted.s.fReading = pAhciPort->Led.Actual.s.fReading = 1; 7178 rc = pAhciPort->pDrvBlock->pfnRead(pAhciPort->pDrvBlock, uOffset, 7179 pSegCurr->pvSeg, cbProcess); 7180 pAhciPort->Led.Actual.s.fReading = 0; 7181 if (RT_FAILURE(rc)) 7182 break; 7183 7184 STAM_REL_COUNTER_ADD(&pAhciPort->StatBytesRead, cbProcess); 7197 7185 } 7198 7186 else 7199 7187 { 7200 /* Add the task to the mask again. */ 7201 ASMAtomicOrU32(&pAhciPort->u32TasksNew, (1 << pAhciPortTaskState->uTag)); 7188 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1; 7189 rc = pAhciPort->pDrvBlock->pfnWrite(pAhciPort->pDrvBlock, uOffset, 7190 pSegCurr->pvSeg, cbProcess); 7191 pAhciPort->Led.Actual.s.fWriting = 0; 7192 if (RT_FAILURE(rc)) 7193 break; 7194 7195 STAM_REL_COUNTER_ADD(&pAhciPort->StatBytesWritten, cbProcess); 7202 7196 } 7197 7198 /* Go to the next entry. */ 7199 uOffset += cbProcess; 7200 cbTransfer -= cbProcess; 7201 pSegCurr++; 7202 pSGInfoCurr++; 7203 7203 } 7204 else 7204 7205 STAM_PROFILE_STOP(&pAhciPort->StatProfileReadWrite, b); 7206 7207 /* Log the error. */ 7208 if ( RT_FAILURE(rc) 7209 && pAhciPort->cErrors++ < MAX_LOG_REL_ERRORS) 7205 7210 { 7206 pAhciPortTaskState->uATARegError = 0; 7207 pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_SEEK; 7211 LogRel(("AHCI#%u: %s at offset %llu (%u bytes left) returned rc=%Rrc\n", 7212 pAhciPort->iLUN, 7213 enmTxDir == AHCITXDIR_READ 7214 ? "Read" 7215 : "Write", 7216 uOffset, cbTransfer, rc)); 7208 7217 } 7209 7218 7210 if (!pAhciPort->fRedo) 7219 /* Cleanup. */ 7220 int rc2 = ahciScatterGatherListDestroy(pAhciPort, pAhciPortTaskState); 7221 if (RT_FAILURE(rc2)) 7222 AssertMsgFailed(("Destroying task list failed rc=%Rrc\n", rc)); 7223 7224 if (RT_LIKELY(!pAhciPort->fPortReset)) 7211 7225 { 7212 /* Write updated command header into memory of the guest. */ 7213 PDMDevHlpPhysWrite(pAhciPort->CTX_SUFF(pDevIns), pAhciPortTaskState->GCPhysCmdHdrAddr, 7214 &pAhciPortTaskState->cmdHdr, sizeof(CmdHdr)); 7215 7216 if (pAhciPortTaskState->fQueued) 7217 ASMAtomicOrU32(&pAhciPort->u32QueuedTasksFinished, (1 << pAhciPortTaskState->uTag)); 7226 pAhciPortTaskState->cmdHdr.u32PRDBC = pAhciPortTaskState->cbTransfer - cbTransfer; 7227 if (RT_FAILURE(rc)) 7228 { 7229 if (!ahciIsRedoSetWarning(pAhciPort, rc)) 7230 { 7231 pAhciPortTaskState->uATARegError = ID_ERR; 7232 pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_ERR; 7233 } 7234 else 7235 { 7236 /* Add the task to the mask again. */ 7237 ASMAtomicOrU32(&pAhciPort->u32TasksNew, (1 << pAhciPortTaskState->uTag)); 7238 } 7239 } 7218 7240 else 7219 7241 { 7220 /* Task is not queued send D2H FIS */7221 ahciSendD2HFis(pAhciPort, pAhciPortTaskState, &pAhciPortTaskState->cmdFis[0], true);7242 pAhciPortTaskState->uATARegError = 0; 7243 pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_SEEK; 7222 7244 } 7223 7245 7224 uIORequestsProcessed++; 7246 if (!pAhciPort->fRedo) 7247 { 7248 /* Write updated command header into memory of the guest. */ 7249 PDMDevHlpPhysWrite(pAhciPort->CTX_SUFF(pDevIns), pAhciPortTaskState->GCPhysCmdHdrAddr, 7250 &pAhciPortTaskState->cmdHdr, sizeof(CmdHdr)); 7251 7252 if (pAhciPortTaskState->fQueued) 7253 ASMAtomicOrU32(&pAhciPort->u32QueuedTasksFinished, (1 << pAhciPortTaskState->uTag)); 7254 else 7255 { 7256 /* Task is not queued send D2H FIS */ 7257 ahciSendD2HFis(pAhciPort, pAhciPortTaskState, &pAhciPortTaskState->cmdFis[0], true); 7258 } 7259 7260 uIORequestsProcessed++; 7261 } 7225 7262 } 7226 7263 }
Note:
See TracChangeset
for help on using the changeset viewer.