- Timestamp:
- Sep 2, 2009 11:08:23 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 51854
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevAHCI.cpp
r22480 r22727 4068 4068 4069 4069 /** 4070 * Fallback scatter gather list creator. 4071 * Used if the normal one fails in PDMDevHlpPhysGCPhys2CCPtr() or 4072 * PDMDevHlpPhysGCPhys2CCPtrReadonly() 4073 * 4074 * returns VBox status code. 4075 * @param pAhciPort The ahci port. 4076 * @param pAhciPortTaskState The task state which contains the S/G list entries. 4077 * @param fReadonly If the mappings should be readonly. 4078 * @param cSGEntriesProcessed Number of entries the normal creator procecssed 4079 * before an error occurred. Used to free 4080 * any ressources allocated before. 4081 * @thread EMT 4082 */ 4083 static int ahciScatterGatherListCreateSafe(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState, 4084 bool fReadonly, unsigned cSGEntriesProcessed) 4085 { 4086 CmdHdr *pCmdHdr = &pAhciPortTaskState->cmdHdr; 4087 PPDMDEVINS pDevIns = pAhciPort->CTX_SUFF(pDevIns); 4088 PAHCIPORTTASKSTATESGENTRY pSGInfoCurr = pAhciPortTaskState->paSGEntries; 4089 4090 AssertPtr(pAhciPortTaskState->pSGListHead); 4091 AssertPtr(pAhciPortTaskState->paSGEntries); 4092 4093 for (unsigned cSGEntryCurr = 0; cSGEntryCurr < cSGEntriesProcessed; cSGEntryCurr++) 4094 { 4095 if (pSGInfoCurr->fGuestMemory) 4096 { 4097 /* Release the lock. */ 4098 PDMDevHlpPhysReleasePageMappingLock(pDevIns, &pSGInfoCurr->u.direct.PageLock); 4099 } 4100 4101 /* Go to the next entry. */ 4102 pSGInfoCurr++; 4103 } 4104 4105 if (pAhciPortTaskState->pvBufferUnaligned) 4106 RTMemFree(pAhciPortTaskState->pvBufferUnaligned); 4107 4108 pAhciPortTaskState->cSGListTooBig = 0; 4109 4110 RTMemFree(pAhciPortTaskState->pSGListHead); 4111 RTMemFree(pAhciPortTaskState->paSGEntries); 4112 pAhciPortTaskState->cSGEntries = 1; 4113 pAhciPortTaskState->cSGListSize = 1; 4114 pAhciPortTaskState->cbBufferUnaligned = pAhciPortTaskState->cbTransfer; 4115 4116 /* Allocate new buffers and SG lists. */ 4117 pAhciPortTaskState->pvBufferUnaligned = RTMemAlloc(pAhciPortTaskState->cbTransfer); 4118 if (!pAhciPortTaskState->pvBufferUnaligned) 4119 return VERR_NO_MEMORY; 4120 4121 pAhciPortTaskState->pSGListHead = (PPDMDATASEG)RTMemAllocZ(1 * sizeof(PDMDATASEG)); 4122 if (!pAhciPortTaskState->pSGListHead) 4123 { 4124 RTMemFree(pAhciPortTaskState->pvBufferUnaligned); 4125 return VERR_NO_MEMORY; 4126 } 4127 4128 pAhciPortTaskState->paSGEntries = (PAHCIPORTTASKSTATESGENTRY)RTMemAllocZ(1 * sizeof(AHCIPORTTASKSTATESGENTRY)); 4129 if (!pAhciPortTaskState->paSGEntries) 4130 { 4131 RTMemFree(pAhciPortTaskState->pvBufferUnaligned); 4132 RTMemFree(pAhciPortTaskState->pSGListHead); 4133 return VERR_NO_MEMORY; 4134 } 4135 4136 /* Set pointers. */ 4137 pAhciPortTaskState->pSGListHead[0].cbSeg = pAhciPortTaskState->cbTransfer; 4138 pAhciPortTaskState->pSGListHead[0].pvSeg = pAhciPortTaskState->pvBufferUnaligned; 4139 4140 pAhciPortTaskState->paSGEntries[0].fGuestMemory = false; 4141 pAhciPortTaskState->paSGEntries[0].u.temp.cUnaligned = AHCI_CMDHDR_PRDTL_ENTRIES(pCmdHdr->u32DescInf); 4142 pAhciPortTaskState->paSGEntries[0].u.temp.GCPhysAddrBaseFirstUnaligned = AHCI_RTGCPHYS_FROM_U32(pCmdHdr->u32CmdTblAddrUp, pCmdHdr->u32CmdTblAddr) + AHCI_CMDHDR_PRDT_OFFSET; 4143 4144 if (pAhciPortTaskState->uTxDir == PDMBLOCKTXDIR_TO_DEVICE) 4145 ahciCopyFromSGListIntoBuffer(pDevIns, &pAhciPortTaskState->paSGEntries[0]); 4146 4147 return VINF_SUCCESS; 4148 } 4149 4150 /** 4070 4151 * Create scatter gather list descriptors. 4071 4152 * … … 4082 4163 PPDMDEVINS pDevIns = pAhciPort->CTX_SUFF(pDevIns); 4083 4164 unsigned cActualSGEntry; 4084 unsigned cSGEntriesR3 = 0; /* Needed scatter gather list entries in R3. */ 4165 unsigned cSGEntriesR3 = 0; /* Needed scatter gather list entries in R3. */ 4166 unsigned cSGEntriesProcessed = 0; /* Number of SG entries procesed. */ 4085 4167 SGLEntry aSGLEntry[32]; /* Holds read sg entries from guest. Biggest seen number of entries a guest set up. */ 4086 4168 unsigned cSGLEntriesGCRead; … … 4219 4301 pSGInfoCurr++; 4220 4302 pSGEntryCurr++; 4303 cSGEntriesProcessed++; 4221 4304 } 4222 4305 } … … 4303 4386 4304 4387 if (RT_FAILURE(rc)) 4305 AssertMsgFailed(("Creating mapping failed rc=%Rrc\n", rc)); 4388 { 4389 /* Mapping failed. Fall back to a bounce buffer. */ 4390 ahciLog(("%s: Mapping guest physical address %RGp failed with rc=%Rc\n", 4391 __FUNCTION__, GCPhysBufferPageAligned, rc)); 4392 4393 return ahciScatterGatherListCreateSafe(pAhciPort, pAhciPortTaskState, fReadonly, 4394 cSGEntriesProcessed); 4395 } 4306 4396 4307 4397 if ((pbMapping + (GCPhysAddrDataBase - GCPhysBufferPageAligned) == ((uint8_t *)pSGEntryPrev->pvSeg + pSGEntryCurr->cbSeg))) … … 4329 4419 pSGInfoPrev = pSGInfoCurr; 4330 4420 pSGInfoCurr++; 4421 cSGEntriesProcessed++; 4331 4422 } 4332 4423 else … … 4371 4462 4372 4463 if (RT_FAILURE(rc)) 4373 AssertMsgFailed(("Creating mapping failed rc=%Rrc\n", rc)); 4464 { 4465 /* Mapping failed. Fall back to a bounce buffer. */ 4466 ahciLog(("%s: Mapping guest physical address %RGp failed with rc=%Rc\n", 4467 __FUNCTION__, GCPhysAddrDataBase, rc)); 4468 4469 return ahciScatterGatherListCreateSafe(pAhciPort, pAhciPortTaskState, fReadonly, 4470 cSGEntriesProcessed); 4471 } 4374 4472 4375 4473 /* Check for adjacent mappings. */ … … 4396 4494 pSGInfoPrev = pSGInfoCurr; 4397 4495 pSGInfoCurr++; 4496 cSGEntriesProcessed++; 4398 4497 } 4399 4498 else
Note:
See TracChangeset
for help on using the changeset viewer.