/** * @copydoc INTNETTRUNKIFPORT::pfnDisconnectAndRelease */ static DECLCALLBACK(void) vboxNetAdpPortDisconnectAndRelease(PINTNETTRUNKIFPORT pIfPort) { PVBOXNETADP pThis = IFPORT_2_VBOXNETADP(pIfPort); RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; /* * Serious paranoia. */ AssertPtr(pThis); Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION); Assert(pThis->MyPort.u32VersionEnd == INTNETTRUNKIFPORT_VERSION); AssertPtr(pThis->pGlobals); Assert(pThis->hEventIdle != NIL_RTSEMEVENT); Assert(pThis->hSpinlock != NIL_RTSPINLOCK); /* * Disconnect and release it. */ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp); //Assert(vboxNetAdpGetState(pThis) == kVBoxNetAdpState_Connected); Assert(!pThis->cBusy); vboxNetAdpSetState(pThis, kVBoxNetAdpState_Transitional); RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp); vboxNetAdpOsDisconnectIt(pThis); pThis->pSwitchPort = NULL; RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp); vboxNetAdpSetState(pThis, kVBoxNetAdpState_Available); RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp); vboxNetAdpRelease(pThis); }
/** * @copydoc INTNETTRUNKIFPORT::pfnWaitForIdle */ static DECLCALLBACK(int) vboxNetAdpPortWaitForIdle(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies) { int rc; PVBOXNETADP pThis = IFPORT_2_VBOXNETADP(pIfPort); /* * Input validation. */ AssertPtr(pThis); Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION); AssertReturn(vboxNetAdpGetStateWithLock(pThis) >= kVBoxNetAdpState_Connected, VERR_INVALID_STATE); /* * Go to sleep on the semaphore after checking the busy count. */ vboxNetAdpRetain(pThis); rc = VINF_SUCCESS; while (pThis->cBusy && RT_SUCCESS(rc)) rc = RTSemEventWait(pThis->hEventIdle, cMillies); /** @todo make interruptible? */ vboxNetAdpRelease(pThis); return rc; }
/** * @copydoc INTNETTRUNKIFPORT::pfnSetActive */ static DECLCALLBACK(bool) vboxNetAdpPortSetActive(PINTNETTRUNKIFPORT pIfPort, bool fActive) { bool fPreviouslyActive; PVBOXNETADP pThis = IFPORT_2_VBOXNETADP(pIfPort); /* * Input validation. */ AssertPtr(pThis); AssertPtr(pThis->pGlobals); Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION); Log(("vboxNetAdpPortSetActive: pThis=%p, fActive=%d, state before: %d.\n", pThis, fActive, vboxNetAdpGetState(pThis))); RTSpinlockAcquire(pThis->hSpinlock); fPreviouslyActive = vboxNetAdpGetState(pThis) == kVBoxNetAdpState_Active; if (fPreviouslyActive != fActive) { switch (vboxNetAdpGetState(pThis)) { case kVBoxNetAdpState_Connected: vboxNetAdpSetState(pThis, kVBoxNetAdpState_Active); break; case kVBoxNetAdpState_Active: vboxNetAdpSetState(pThis, kVBoxNetAdpState_Connected); break; default: break; } } RTSpinlockRelease(pThis->hSpinlock); Log(("vboxNetAdpPortSetActive: state after: %RTbool.\n", vboxNetAdpGetState(pThis))); return fPreviouslyActive; }
/** * @copydoc INTNETTRUNKIFPORT::pfnXmit */ static DECLCALLBACK(int) vboxNetAdpPortXmit(PINTNETTRUNKIFPORT pIfPort, PINTNETSG pSG, uint32_t fDst) { PVBOXNETADP pThis = IFPORT_2_VBOXNETADP(pIfPort); int rc = VINF_SUCCESS; /* * Input validation. */ AssertPtr(pThis); AssertPtr(pSG); Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION); Log(("vboxNetAdpPortXmit: outgoing packet (len=%d)\n", pSG->cbTotal)); /* * Do a retain/busy, invoke the OS specific code. */ RTSpinlockAcquire(pThis->hSpinlock); if (vboxNetAdpGetState(pThis) != kVBoxNetAdpState_Active) { RTSpinlockRelease(pThis->hSpinlock); Log(("vboxNetAdpReceive: Dropping incoming packet for inactive interface %s.\n", pThis->szName)); return VERR_INVALID_STATE; } vboxNetAdpRetain(pThis); vboxNetAdpBusy(pThis); RTSpinlockRelease(pThis->hSpinlock); rc = vboxNetAdpPortOsXmit(pThis, pSG, fDst); vboxNetAdpIdle(pThis); vboxNetAdpRelease(pThis); return rc; }
/** * @copydoc INTNETTRUNKIFPORT::pfnGetMacAddress */ static DECLCALLBACK(void) vboxNetAdpPortGetMacAddress(PINTNETTRUNKIFPORT pIfPort, PRTMAC pMac) { PVBOXNETADP pThis = IFPORT_2_VBOXNETADP(pIfPort); /* * Input validation. */ AssertPtr(pThis); Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION); Assert(vboxNetAdpGetStateWithLock(pThis) == kVBoxNetAdpState_Active); /* * Forward the question to the OS specific code. */ vboxNetAdpPortOsGetMacAddress(pThis, pMac); }
/** * @copydoc INTNETTRUNKIFPORT::pfnRetain */ static DECLCALLBACK(void) vboxNetAdpPortRetain(PINTNETTRUNKIFPORT pIfPort) { PVBOXNETADP pThis = IFPORT_2_VBOXNETADP(pIfPort); vboxNetAdpRetain(pThis); }