- Timestamp:
- Dec 9, 2016 8:32:53 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/VirtIO/Virtio.cpp
r64810 r64825 219 219 } 220 220 221 void vqueuePut(PVPCISTATE pState, PVQUEUE pQueue, PVQUEUEELEM pElem, uint32_t uLen, uint32_t uReserved) 222 { 223 unsigned int i, uOffset, cbReserved = uReserved; 224 225 Log2(("%s vqueuePut: %s desc_idx=%u acb=%u\n", INSTANCE(pState), 226 QUEUENAME(pState, pQueue), pElem->uIndex, uLen)); 227 for (i = uOffset = 0; i < pElem->nIn && uOffset < uLen - uReserved; i++) 228 { 229 uint32_t cbSegLen = RT_MIN(uLen - uReserved - uOffset, pElem->aSegsIn[i].cb - cbReserved); 230 if (pElem->aSegsIn[i].pv) 221 222 void vqueuePut(PVPCISTATE pState, PVQUEUE pQueue, 223 PVQUEUEELEM pElem, uint32_t uTotalLen, uint32_t uReserved) 224 { 225 Log2(("%s vqueuePut: %s" 226 " desc_idx=%u acb=%u (%u)\n", 227 INSTANCE(pState), QUEUENAME(pState, pQueue), 228 pElem->uIndex, uTotalLen, uReserved)); 229 230 Assert(uReserved < uTotalLen); 231 232 uint32_t cbLen = uTotalLen - uReserved; 233 uint32_t cbSkip = uReserved; 234 235 for (unsigned i = 0; i < pElem->nIn && cbLen > 0; ++i) 236 { 237 if (cbSkip >= pElem->aSegsIn[i].cb) /* segment completely skipped? */ 231 238 { 232 if (cbSegLen > 0) 233 { 234 Log2(("%s vqueuePut: %s used_idx=%u seg=%u addr=%p pv=%p cb=%u acb=%u\n", INSTANCE(pState), 235 QUEUENAME(pState, pQueue), pQueue->uNextUsedIndex, i, pElem->aSegsIn[i].addr, pElem->aSegsIn[i].pv, pElem->aSegsIn[i].cb, cbSegLen)); 236 PDMDevHlpPCIPhysWrite(pState->CTX_SUFF(pDevIns), pElem->aSegsIn[i].addr + cbReserved, 237 pElem->aSegsIn[i].pv, cbSegLen); 238 } 239 cbReserved = 0; 239 cbSkip -= pElem->aSegsIn[i].cb; 240 continue; 240 241 } 241 uOffset += cbSegLen; 242 } 243 244 Assert((uReserved + uOffset) == uLen || pElem->nIn == 0); 245 Log2(("%s vqueuePut: %s used_idx=%u guest_used_idx=%u id=%u len=%u\n", INSTANCE(pState), 246 QUEUENAME(pState, pQueue), pQueue->uNextUsedIndex, vringReadUsedIndex(pState, &pQueue->VRing), pElem->uIndex, uLen)); 247 vringWriteUsedElem(pState, &pQueue->VRing, pQueue->uNextUsedIndex++, pElem->uIndex, uLen); 248 } 242 243 uint32_t cbSegLen = pElem->aSegsIn[i].cb - cbSkip; 244 if (cbSegLen > cbLen) /* last segment only partially used? */ 245 cbSegLen = cbLen; 246 247 /* 248 * XXX: We should assert pv != NULL, but we need to check and 249 * fix all callers first. 250 */ 251 if (pElem->aSegsIn[i].pv != NULL) 252 { 253 Log2(("%s vqueuePut: %s" 254 " used_idx=%u seg=%u addr=%p pv=%p cb=%u acb=%u\n", 255 INSTANCE(pState), QUEUENAME(pState, pQueue), 256 pQueue->uNextUsedIndex, i, 257 (void *)pElem->aSegsIn[i].addr, pElem->aSegsIn[i].pv, 258 pElem->aSegsIn[i].cb, cbSegLen)); 259 260 PDMDevHlpPCIPhysWrite(pState->CTX_SUFF(pDevIns), 261 pElem->aSegsIn[i].addr + cbSkip, 262 pElem->aSegsIn[i].pv, 263 cbSegLen); 264 } 265 266 cbSkip = 0; 267 cbLen -= cbSegLen; 268 } 269 270 Log2(("%s vqueuePut: %s" 271 " used_idx=%u guest_used_idx=%u id=%u len=%u\n", 272 INSTANCE(pState), QUEUENAME(pState, pQueue), 273 pQueue->uNextUsedIndex, vringReadUsedIndex(pState, &pQueue->VRing), 274 pElem->uIndex, uTotalLen)); 275 276 vringWriteUsedElem(pState, &pQueue->VRing, 277 pQueue->uNextUsedIndex++, 278 pElem->uIndex, uTotalLen); 279 } 280 249 281 250 282 void vqueueNotify(PVPCISTATE pState, PVQUEUE pQueue)
Note:
See TracChangeset
for help on using the changeset viewer.