void vqueueNotify(PVPCISTATE pState, PVQUEUE pQueue) { LogFlow(("%s vqueueNotify: %s availFlags=%x guestFeatures=%x vqueue is %sempty\n", INSTANCE(pState), QUEUENAME(pState, pQueue), vringReadAvailFlags(pState, &pQueue->VRing), pState->uGuestFeatures, vqueueIsEmpty(pState, pQueue)?"":"not ")); if (!(vringReadAvailFlags(pState, &pQueue->VRing) & VRINGAVAIL_F_NO_INTERRUPT) || ((pState->uGuestFeatures & VPCI_F_NOTIFY_ON_EMPTY) && vqueueIsEmpty(pState, pQueue))) { int rc = vpciRaiseInterrupt(pState, VERR_INTERNAL_ERROR, VPCI_ISR_QUEUE); if (RT_FAILURE(rc)) Log(("%s vqueueNotify: Failed to raise an interrupt (%Rrc).\n", INSTANCE(pState), rc)); } else { STAM_COUNTER_INC(&pState->StatIntsSkipped); } }
bool vqueueSkip(PVPCISTATE pState, PVQUEUE pQueue) { if (vqueueIsEmpty(pState, pQueue)) return false; Log2(("%s vqueueSkip: %s avail_idx=%u\n", INSTANCE(pState), QUEUENAME(pState, pQueue), pQueue->uNextAvailIndex)); pQueue->uNextAvailIndex++; return true; }
bool vqueueGet(PVPCISTATE pState, PVQUEUE pQueue, PVQUEUEELEM pElem, bool fRemove) { if (vqueueIsEmpty(pState, pQueue)) return false; pElem->nIn = pElem->nOut = 0; Log2(("%s vqueueGet: %s avail_idx=%u\n", INSTANCE(pState), QUEUENAME(pState, pQueue), pQueue->uNextAvailIndex)); VRINGDESC desc; uint16_t idx = vringReadAvail(pState, &pQueue->VRing, pQueue->uNextAvailIndex); if (fRemove) pQueue->uNextAvailIndex++; pElem->uIndex = idx; do { VQUEUESEG *pSeg; vringReadDesc(pState, &pQueue->VRing, idx, &desc); if (desc.u16Flags & VRINGDESC_F_WRITE) { Log2(("%s vqueueGet: %s IN seg=%u desc_idx=%u addr=%p cb=%u\n", INSTANCE(pState), QUEUENAME(pState, pQueue), pElem->nIn, idx, desc.u64Addr, desc.uLen)); pSeg = &pElem->aSegsIn[pElem->nIn++]; } else { Log2(("%s vqueueGet: %s OUT seg=%u desc_idx=%u addr=%p cb=%u\n", INSTANCE(pState), QUEUENAME(pState, pQueue), pElem->nOut, idx, desc.u64Addr, desc.uLen)); pSeg = &pElem->aSegsOut[pElem->nOut++]; } pSeg->addr = desc.u64Addr; pSeg->cb = desc.uLen; pSeg->pv = NULL; idx = desc.u16Next; } while (desc.u16Flags & VRINGDESC_F_NEXT); Log2(("%s vqueueGet: %s head_desc_idx=%u nIn=%u nOut=%u\n", INSTANCE(pState), QUEUENAME(pState, pQueue), pElem->uIndex, pElem->nIn, pElem->nOut)); return true; }