Changeset 23467 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Oct 1, 2009 10:15:35 AM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 53076
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevAHCI.cpp
r23149 r23467 207 207 /** Pointer to a pointer of a scatter gather list entry. */ 208 208 typedef PAHCIPORTTASKSTATESGENTRY *PPAHCIPORTTASKSTATESGENTRY; 209 /** Pointer to a task state. */ 210 typedef struct AHCIPORTTASKSTATE *PAHCIPORTTASKSTATE; 211 212 /** 213 * Data processing callback 214 * 215 * @returns VBox status. 216 * @param pAhciPortTaskState The task state. 217 */ 218 typedef DECLCALLBACK(int) FNAHCIPOSTPROCESS(PAHCIPORTTASKSTATE pAhciPortTaskState); 219 /** Pointer to a FNAHCIPOSTPROCESS() function. */ 220 typedef FNAHCIPOSTPROCESS *PFNAHCIPOSTPROCESS; 209 221 210 222 /** … … 235 247 /** ATA status register */ 236 248 uint8_t uATARegStatus; 249 /** How many entries would fit into the sg list. */ 250 uint32_t cSGListSize; 251 /** Number of used SG list entries. */ 252 uint32_t cSGListUsed; 253 /** Pointer to the first entry of the scatter gather list. */ 254 PPDMDATASEG pSGListHead; 237 255 /** Number of scatter gather list entries. */ 238 256 uint32_t cSGEntries; 239 /** How many entries would fit into the sg list. */ 240 uint32_t cSGListSize; 241 /** Pointer to the first entry of the scatter gather list. */ 242 PPDMDATASEG pSGListHead; 257 /** Total number of bytes the guest reserved for this request. 258 * Sum of all SG entries. */ 259 uint32_t cbSGBuffers; 243 260 /** Pointer to the first mapping information entry. */ 244 261 PAHCIPORTTASKSTATESGENTRY paSGEntries; … … 249 266 /** Number of times in a row the scatter gather list was too big. */ 250 267 uint32_t cSGListTooBig; 251 } AHCIPORTTASKSTATE, *PAHCIPORTTASKSTATE; 268 /** Post processing callback. 269 * If this is set we will use a buffer for the data 270 * and the callback copies the data to the destination. */ 271 PFNAHCIPOSTPROCESS pfnPostProcess; 272 } AHCIPORTTASKSTATE; 252 273 253 274 /** … … 810 831 static void ahciCopyFromBufferIntoSGList(PPDMDEVINS pDevIns, PAHCIPORTTASKSTATESGENTRY pSGInfo); 811 832 static void ahciCopyFromSGListIntoBuffer(PPDMDEVINS pDevIns, PAHCIPORTTASKSTATESGENTRY pSGInfo); 833 static void ahciScatterGatherListGetTotalBufferSize(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState); 834 static int ahciScatterGatherListCreateSafe(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState, 835 bool fReadonly, unsigned cSGEntriesProcessed); 812 836 #endif 813 837 RT_C_DECLS_END … … 2910 2934 2911 2935 /* Copy the buffer in to the scatter gather list. */ 2912 ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&p[0], sizeof(p)); 2913 *pcbData = sizeof(p); 2936 *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&p[0], sizeof(p)); 2914 2937 2915 2938 atapiCmdOK(pAhciPort, pAhciPortTaskState); … … 2925 2948 2926 2949 /* Copy the buffer in to the scatter gather list. */ 2927 ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 2928 *pcbData = sizeof(aBuf); 2950 *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 2929 2951 2930 2952 atapiCmdOK(pAhciPort, pAhciPortTaskState); … … 2953 2975 2954 2976 /* Copy the buffer in to the scatter gather list. */ 2955 ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 2956 *pcbData = sizeof(aBuf); 2977 *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 2957 2978 2958 2979 atapiCmdOK(pAhciPort, pAhciPortTaskState); … … 2984 3005 2985 3006 /* Copy the buffer in to the scatter gather list. */ 2986 ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 2987 *pcbData = sizeof(aBuf); 3007 *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 2988 3008 2989 3009 atapiCmdOK(pAhciPort, pAhciPortTaskState); … … 3020 3040 3021 3041 /* Copy the buffer in to the scatter gather list. */ 3022 ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 3023 *pcbData = sizeof(aBuf); 3042 *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 3024 3043 3025 3044 atapiCmdOK(pAhciPort, pAhciPortTaskState); … … 3045 3064 3046 3065 /* Copy the buffer in to the scatter gather list. */ 3047 ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 3048 *pcbData = sizeof(aBuf); 3066 *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 3049 3067 3050 3068 atapiCmdOK(pAhciPort, pAhciPortTaskState); … … 3075 3093 3076 3094 /* Copy the buffer in to the scatter gather list. */ 3077 ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 3078 *pcbData = sizeof(aBuf); 3095 *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 3079 3096 3080 3097 atapiCmdOK(pAhciPort, pAhciPortTaskState); … … 3126 3143 3127 3144 /* Copy the buffer in to the scatter gather list. */ 3128 ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 3129 *pcbData = sizeof(aBuf); 3145 *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 3130 3146 3131 3147 atapiCmdOK(pAhciPort, pAhciPortTaskState); … … 3145 3161 3146 3162 /* Copy the buffer in to the scatter gather list. */ 3147 ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 3148 *pcbData = sizeof(aBuf); 3163 *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 3149 3164 3150 3165 atapiCmdOK(pAhciPort, pAhciPortTaskState); … … 3166 3181 3167 3182 /* Copy the buffer in to the scatter gather list. */ 3168 ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 3169 *pcbData = sizeof(aBuf); 3183 *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 3170 3184 3171 3185 atapiCmdOK(pAhciPort, pAhciPortTaskState); … … 3229 3243 3230 3244 /* Copy the buffer in to the scatter gather list. */ 3231 ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], cbSize); 3232 *pcbData = cbSize; 3245 *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], cbSize); 3233 3246 3234 3247 atapiCmdOK(pAhciPort, pAhciPortTaskState); … … 3263 3276 3264 3277 /* Copy the buffer in to the scatter gather list. */ 3265 ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 3266 *pcbData = sizeof(aBuf); 3278 *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf)); 3267 3279 3268 3280 atapiCmdOK(pAhciPort, pAhciPortTaskState); … … 3352 3364 3353 3365 /* Copy the buffer in to the scatter gather list. */ 3354 ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], cbSize); 3355 *pcbData = cbSize; 3366 *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], cbSize); 3356 3367 3357 3368 atapiCmdOK(pAhciPort, pAhciPortTaskState); … … 3364 3375 int rc, rcSourceSink; 3365 3376 3366 /* Create scatter gather list. */ 3367 rc = ahciScatterGatherListCreate(pAhciPort, pAhciPortTaskState, false); 3368 if (RT_FAILURE(rc)) 3369 AssertMsgFailed(("Getting number of list elements failed rc=%Rrc\n", rc)); 3377 /* 3378 * Create scatter gather list. We use a safe mapping here because it is 3379 * possible that the buffer is not a multiple of 512. The normal 3380 * creator would assert later here. 3381 */ 3382 ahciScatterGatherListGetTotalBufferSize(pAhciPort, pAhciPortTaskState); 3383 rc = ahciScatterGatherListCreateSafe(pAhciPort, pAhciPortTaskState, false, 0); 3384 AssertRC(rc); 3370 3385 3371 3386 rcSourceSink = g_apfnAtapiFuncs[iSourceSink](pAhciPortTaskState, pAhciPort, &cbTransfered); … … 3374 3389 3375 3390 rc = ahciScatterGatherListDestroy(pAhciPort, pAhciPortTaskState); 3376 if (RT_FAILURE(rc)) 3377 AssertMsgFailed(("Destroying list failed rc=%Rrc\n", rc)); 3391 AssertRC(rc); 3378 3392 3379 3393 /* Write updated command header into memory of the guest. */ … … 3381 3395 3382 3396 return rcSourceSink; 3397 } 3398 3399 static int atapiReadSectors2352PostProcess(PAHCIPORTTASKSTATE pAhciPortTaskState) 3400 { 3401 uint32_t cSectors = pAhciPortTaskState->cbTransfer / 2048; 3402 uint32_t iATAPILBA = pAhciPortTaskState->uOffset / 2048; 3403 uint8_t *pbBufDst = (uint8_t *)pAhciPortTaskState->pvBufferUnaligned; 3404 uint8_t *pbBufSrc = (uint8_t *)pAhciPortTaskState->pSGListHead[0].pvSeg; 3405 3406 for (uint32_t i = iATAPILBA; i < iATAPILBA + cSectors; i++) 3407 { 3408 /* sync bytes */ 3409 *pbBufDst++ = 0x00; 3410 memset(pbBufDst, 0xff, 11); 3411 pbBufDst += 11; 3412 /* MSF */ 3413 ataLBA2MSF(pbBufDst, i); 3414 pbBufDst += 3; 3415 *pbBufDst++ = 0x01; /* mode 1 data */ 3416 /* data */ 3417 memcpy(pbBufDst, pbBufSrc, 2048); 3418 pbBufDst += 2048; 3419 pbBufSrc += 2048; 3420 /* ECC */ 3421 memset(pbBufDst, 0, 288); 3422 pbBufDst += 288; 3423 } 3424 3425 return VINF_SUCCESS; 3383 3426 } 3384 3427 … … 3394 3437 break; 3395 3438 case 2352: 3396 { 3397 AssertMsgFailed(("2352 read\n")); 3398 /* @todo: This is quite difficult as the data transfer is not handled here 3399 We need to add the sync bytes etc. here and modify the pointers 3400 and size of the sg entries. */ 3401 #if 0 3402 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer); 3403 3404 for (uint32_t i = s->iATAPILBA; i < s->iATAPILBA + cSectors; i++) 3405 { 3406 /* sync bytes */ 3407 *pbBuf++ = 0x00; 3408 memset(pbBuf, 0xff, 11); 3409 pbBuf += 11; 3410 /* MSF */ 3411 ataLBA2MSF(pbBuf, i); 3412 pbBuf += 3; 3413 *pbBuf++ = 0x01; /* mode 1 data */ 3414 /* data */ 3415 rc = s->pDrvBlock->pfnRead(s->pDrvBlock, (uint64_t)i * 2048, pbBuf, 2048); 3416 if (RT_FAILURE(rc)) 3417 break; 3418 pbBuf += 2048; 3419 /* ECC */ 3420 memset(pbBuf, 0, 288); 3421 pbBuf += 288; 3422 } 3423 #endif 3424 pAhciPortTaskState->uOffset = iATAPILBA * 2048; 3425 pAhciPortTaskState->cbTransfer = cSectors * 2048; 3426 } 3439 { 3440 pAhciPortTaskState->pfnPostProcess = atapiReadSectors2352PostProcess; 3441 pAhciPortTaskState->uOffset = iATAPILBA * 2048; 3442 pAhciPortTaskState->cbTransfer = cSectors * 2048; 3427 3443 break; 3444 } 3428 3445 default: 3429 3446 AssertMsgFailed(("Unsupported sectors size\n")); … … 3996 4013 } 3997 4014 4015 static void ahciScatterGatherListGetTotalBufferSize(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState) 4016 { 4017 CmdHdr *pCmdHdr = &pAhciPortTaskState->cmdHdr; 4018 PPDMDEVINS pDevIns = pAhciPort->CTX_SUFF(pDevIns); 4019 unsigned cActualSGEntry; 4020 SGLEntry aSGLEntry[32]; /* Holds read sg entries from guest. Biggest seen number of entries a guest set up. */ 4021 unsigned cSGLEntriesGCRead; 4022 unsigned cSGLEntriesGCLeft; /* Available scatter gather list entries in GC */ 4023 RTGCPHYS GCPhysAddrPRDTLEntryStart; /* Start address to read the entries from. */ 4024 uint32_t cbSGBuffers = 0; /* Total number of bytes reserved for this request. */ 4025 4026 /* Retrieve the total number of bytes reserved for this request. */ 4027 cSGLEntriesGCLeft = AHCI_CMDHDR_PRDTL_ENTRIES(pCmdHdr->u32DescInf); 4028 ahciLog(("%s: cSGEntriesGC=%u\n", __FUNCTION__, cSGLEntriesGCLeft)); 4029 4030 /* Set start address of the entries. */ 4031 GCPhysAddrPRDTLEntryStart = AHCI_RTGCPHYS_FROM_U32(pCmdHdr->u32CmdTblAddrUp, pCmdHdr->u32CmdTblAddr) + AHCI_CMDHDR_PRDT_OFFSET; 4032 4033 do 4034 { 4035 cSGLEntriesGCRead = (cSGLEntriesGCLeft < RT_ELEMENTS(aSGLEntry)) ? cSGLEntriesGCLeft : RT_ELEMENTS(aSGLEntry); 4036 cSGLEntriesGCLeft -= cSGLEntriesGCRead; 4037 4038 /* Read the SG entries. */ 4039 PDMDevHlpPhysRead(pDevIns, GCPhysAddrPRDTLEntryStart, &aSGLEntry[0], cSGLEntriesGCRead * sizeof(SGLEntry)); 4040 4041 for (cActualSGEntry = 0; cActualSGEntry < cSGLEntriesGCRead; cActualSGEntry++) 4042 cbSGBuffers += (aSGLEntry[cActualSGEntry].u32DescInf & SGLENTRY_DESCINF_DBC) + 1; 4043 4044 /* Set address to the next entries to read. */ 4045 GCPhysAddrPRDTLEntryStart += cSGLEntriesGCRead * sizeof(SGLEntry); 4046 4047 } while (cSGLEntriesGCLeft); 4048 4049 pAhciPortTaskState->cbSGBuffers = cbSGBuffers; 4050 } 4051 3998 4052 static int ahciScatterGatherListAllocate(PAHCIPORTTASKSTATE pAhciPortTaskState, uint32_t cSGList, uint32_t cbUnaligned) 3999 4053 { … … 4069 4123 * Fallback scatter gather list creator. 4070 4124 * Used if the normal one fails in PDMDevHlpPhysGCPhys2CCPtr() or 4071 * PDMDevHlpPhysGCPhys2CCPtrReadonly() 4125 * PDMDevHlpPhysGCPhys2CCPtrReadonly() or post processing 4126 * is used. 4072 4127 * 4073 4128 * returns VBox status code. … … 4087 4142 PAHCIPORTTASKSTATESGENTRY pSGInfoCurr = pAhciPortTaskState->paSGEntries; 4088 4143 4089 Assert Ptr(pAhciPortTaskState->pSGListHead);4090 Assert Ptr(pAhciPortTaskState->paSGEntries);4144 Assert(VALID_PTR(pAhciPortTaskState->pSGListHead) || !cSGEntriesProcessed); 4145 Assert(VALID_PTR(pAhciPortTaskState->paSGEntries) || !cSGEntriesProcessed); 4091 4146 4092 4147 for (unsigned cSGEntryCurr = 0; cSGEntryCurr < cSGEntriesProcessed; cSGEntryCurr++) … … 4103 4158 4104 4159 if (pAhciPortTaskState->pvBufferUnaligned) 4160 { 4105 4161 RTMemFree(pAhciPortTaskState->pvBufferUnaligned); 4106 4107 pAhciPortTaskState->cSGListTooBig = 0; 4108 4109 RTMemFree(pAhciPortTaskState->pSGListHead); 4110 RTMemFree(pAhciPortTaskState->paSGEntries); 4111 pAhciPortTaskState->cSGEntries = 1; 4112 pAhciPortTaskState->cSGListSize = 1; 4113 pAhciPortTaskState->cbBufferUnaligned = pAhciPortTaskState->cbTransfer; 4162 pAhciPortTaskState->pvBufferUnaligned = NULL; 4163 } 4164 if (pAhciPortTaskState->pSGListHead) 4165 { 4166 RTMemFree(pAhciPortTaskState->pSGListHead); 4167 pAhciPortTaskState->pSGListHead = NULL; 4168 } 4169 if (pAhciPortTaskState->paSGEntries) 4170 { 4171 RTMemFree(pAhciPortTaskState->paSGEntries); 4172 pAhciPortTaskState->paSGEntries = NULL; 4173 } 4174 pAhciPortTaskState->cSGListTooBig = 0; 4175 pAhciPortTaskState->cSGEntries = 1; 4176 pAhciPortTaskState->cSGListUsed = 1; 4177 pAhciPortTaskState->cSGListSize = 1; 4178 pAhciPortTaskState->cbBufferUnaligned = pAhciPortTaskState->cbSGBuffers; 4114 4179 4115 4180 /* Allocate new buffers and SG lists. */ 4116 pAhciPortTaskState->pvBufferUnaligned = RTMemAlloc(pAhciPortTaskState->cb Transfer);4181 pAhciPortTaskState->pvBufferUnaligned = RTMemAlloc(pAhciPortTaskState->cbSGBuffers); 4117 4182 if (!pAhciPortTaskState->pvBufferUnaligned) 4118 4183 return VERR_NO_MEMORY; … … 4134 4199 4135 4200 /* Set pointers. */ 4136 pAhciPortTaskState->pSGListHead[0].cbSeg = pAhciPortTaskState->cbTransfer; 4137 pAhciPortTaskState->pSGListHead[0].pvSeg = pAhciPortTaskState->pvBufferUnaligned; 4201 if (pAhciPortTaskState->cbTransfer) 4202 { 4203 pAhciPortTaskState->pSGListHead[0].cbSeg = pAhciPortTaskState->cbTransfer; 4204 4205 /* Allocate a separate buffer if we have to do post processing . */ 4206 if (pAhciPortTaskState->pfnPostProcess) 4207 { 4208 pAhciPortTaskState->pSGListHead[0].pvSeg = RTMemAlloc(pAhciPortTaskState->cbTransfer); 4209 if (!pAhciPortTaskState->pSGListHead[0].pvSeg) 4210 { 4211 RTMemFree(pAhciPortTaskState->paSGEntries); 4212 RTMemFree(pAhciPortTaskState->pvBufferUnaligned); 4213 RTMemFree(pAhciPortTaskState->pSGListHead); 4214 return VERR_NO_MEMORY; 4215 } 4216 } 4217 else 4218 pAhciPortTaskState->pSGListHead[0].pvSeg = pAhciPortTaskState->pvBufferUnaligned; 4219 } 4220 else 4221 { 4222 pAhciPortTaskState->pSGListHead[0].cbSeg = pAhciPortTaskState->cbBufferUnaligned; 4223 pAhciPortTaskState->pSGListHead[0].pvSeg = pAhciPortTaskState->pvBufferUnaligned; 4224 } 4138 4225 4139 4226 pAhciPortTaskState->paSGEntries[0].fGuestMemory = false; … … 4174 4261 uint32_t cUnaligned; 4175 4262 bool fDoMapping = false; 4263 uint32_t cbSGBuffers = 0; /* Total number of bytes reserved for this request. */ 4176 4264 RTGCPHYS GCPhysAddrPRDTLUnalignedStart = NIL_RTGCPHYS; 4177 4265 PAHCIPORTTASKSTATESGENTRY pSGInfoCurr = NULL; … … 4184 4272 4185 4273 STAM_PROFILE_START(&pAhciPort->StatProfileMapIntoR3, a); 4274 4275 pAhciPortTaskState->cbSGBuffers = 0; 4276 4277 /* 4278 * Create a safe mapping when doing post processing because the size of the 4279 * data to transfer and the amount of guest memory reserved can differ 4280 */ 4281 if (pAhciPortTaskState->pfnPostProcess) 4282 { 4283 ahciLog(("%s: Request with post processing.\n")); 4284 4285 ahciScatterGatherListGetTotalBufferSize(pAhciPort, pAhciPortTaskState); 4286 4287 return ahciScatterGatherListCreateSafe(pAhciPort, pAhciPortTaskState, fReadonly, 0); 4288 } 4186 4289 4187 4290 /* … … 4220 4323 pSGInfoCurr->fGuestMemory= false; 4221 4324 pu8BufferUnalignedPos = (uint8_t *)pAhciPortTaskState->pvBufferUnaligned; 4325 pAhciPortTaskState->cSGListUsed = 0; 4326 pAhciPortTaskState->cbSGBuffers = cbSGBuffers; 4222 4327 } 4223 4328 … … 4239 4344 cbDataToTransfer = (aSGLEntry[cActualSGEntry].u32DescInf & SGLENTRY_DESCINF_DBC) + 1; 4240 4345 ahciLog(("%s: cbDataToTransfer=%u\n", __FUNCTION__, cbDataToTransfer)); 4346 cbSGBuffers += cbDataToTransfer; 4241 4347 4242 4348 /* Check if the buffer is sector aligned. */ … … 4301 4407 pSGInfoCurr++; 4302 4408 pSGEntryCurr++; 4409 pAhciPortTaskState->cSGListUsed++; 4303 4410 cSGEntriesProcessed++; 4304 4411 } … … 4415 4522 pSGEntryPrev = pSGEntryCurr; 4416 4523 pSGEntryCurr++; 4524 pAhciPortTaskState->cSGListUsed++; 4417 4525 } 4418 4526 … … 4490 4598 pSGEntryPrev = pSGEntryCurr; 4491 4599 pSGEntryCurr++; 4600 pAhciPortTaskState->cSGListUsed++; 4492 4601 } 4493 4602 … … 4530 4639 pSGEntryCurr->pvSeg = pu8BufferUnalignedPos; 4531 4640 pSGEntryCurr->cbSeg = cbUnaligned; 4641 pAhciPortTaskState->cSGListUsed++; 4532 4642 4533 4643 /* … … 4557 4667 4558 4668 STAM_PROFILE_START(&pAhciPort->StatProfileDestroyScatterGatherList, a); 4669 4670 if (pAhciPortTaskState->pfnPostProcess) 4671 { 4672 int rc; 4673 rc = pAhciPortTaskState->pfnPostProcess(pAhciPortTaskState); 4674 AssertRC(rc); 4675 4676 pAhciPortTaskState->pfnPostProcess = NULL; 4677 4678 /* Free the buffer holding the unprocessed data. They are not needed anymore. */ 4679 RTMemFree(pAhciPortTaskState->pSGListHead[0].pvSeg); 4680 } 4559 4681 4560 4682 for (unsigned cActualSGEntry = 0; cActualSGEntry < pAhciPortTaskState->cSGEntries; cActualSGEntry++) … … 4682 4804 * Copy the content of a buffer to a scatter gather list. 4683 4805 * 4684 * @returns VBox status code.4806 * @returns Number of bytes transfered. 4685 4807 * @param pAhciPortTaskState The task state which contains the S/G list entries. 4686 4808 * @param pvBuf Pointer to the buffer which should be copied. … … 4690 4812 { 4691 4813 unsigned cSGEntry = 0; 4814 int cbCopied = 0; 4692 4815 PPDMDATASEG pSGEntry = &pAhciPortTaskState->pSGListHead[cSGEntry]; 4693 4816 uint8_t *pu8Buf = (uint8_t *)pvBuf; … … 4695 4818 while (cSGEntry < pAhciPortTaskState->cSGEntries) 4696 4819 { 4697 size_t cbToCopy = (cbBuf < pSGEntry->cbSeg) ? cbBuf : pSGEntry->cbSeg;4820 size_t cbToCopy = RT_MIN(cbBuf, pSGEntry->cbSeg); 4698 4821 4699 4822 memcpy(pSGEntry->pvSeg, pu8Buf, cbToCopy); 4700 4823 4701 4824 cbBuf -= cbToCopy; 4825 cbCopied += cbToCopy; 4826 4702 4827 /* We finished. */ 4703 4828 if (!cbBuf) … … 4712 4837 } 4713 4838 4714 #if 0 4715 if (!pAhciPort->fATAPI) 4716 AssertMsg(!cbBuf, ("There is still data in the buffer\n")); 4717 #endif 4718 return VINF_SUCCESS; 4839 LogFlow(("%s: Copied %d bytes\n", __FUNCTION__, cbCopied)); 4840 return cbCopied; 4719 4841 } 4720 4842 … … 4810 4932 AssertMsg(pCmdFis[AHCI_CMDFIS_TYPE] == AHCI_CMDFIS_TYPE_H2D, ("FIS is not a host to device Fis!!\n")); 4811 4933 4934 pAhciPortTaskState->cbTransfer = 0; 4935 4812 4936 switch (pCmdFis[AHCI_CMDFIS_CMD]) 4813 4937 { … … 4827 4951 4828 4952 /* Copy the buffer. */ 4829 rc = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, &u16Temp[0], sizeof(u16Temp)); 4830 if (RT_FAILURE(rc)) 4831 AssertMsgFailed(("Copying failed rc=%Rrc\n", rc)); 4953 pCmdHdr->u32PRDBC = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, &u16Temp[0], sizeof(u16Temp)); 4832 4954 4833 4955 /* Destroy list. */ … … 4838 4960 pAhciPortTaskState->uATARegError = 0; 4839 4961 pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_SEEK; 4840 pCmdHdr->u32PRDBC = sizeof(u16Temp);4841 4962 4842 4963 /* Write updated command header into memory of the guest. */ … … 5187 5308 pAhciPort->Led.Asserted.s.fReading = pAhciPort->Led.Actual.s.fReading = 1; 5188 5309 rc = pAhciPort->pDrvBlockAsync->pfnStartRead(pAhciPort->pDrvBlockAsync, pAhciPortTaskState->uOffset, 5189 pAhciPortTaskState->pSGListHead, pAhciPortTaskState->cSG Entries,5310 pAhciPortTaskState->pSGListHead, pAhciPortTaskState->cSGListUsed, 5190 5311 pAhciPortTaskState->cbTransfer, 5191 5312 pAhciPortTaskState); … … 5195 5316 pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1; 5196 5317 rc = pAhciPort->pDrvBlockAsync->pfnStartWrite(pAhciPort->pDrvBlockAsync, pAhciPortTaskState->uOffset, 5197 pAhciPortTaskState->pSGListHead, pAhciPortTaskState->cSG Entries,5318 pAhciPortTaskState->pSGListHead, pAhciPortTaskState->cSGListUsed, 5198 5319 pAhciPortTaskState->cbTransfer, 5199 5320 pAhciPortTaskState); … … 5402 5523 STAM_PROFILE_START(&pAhciPort->StatProfileReadWrite, a); 5403 5524 5404 while (cbTransfer)5525 while (cbTransfer) 5405 5526 { 5406 5527 size_t cbProcess = (cbTransfer < pSegCurr->cbSeg) ? cbTransfer : pSegCurr->cbSeg;
Note:
See TracChangeset
for help on using the changeset viewer.