VirtualBox

Changeset 26001 in vbox for trunk/src/VBox/Devices/Network


Ignore:
Timestamp:
Jan 25, 2010 2:21:13 PM (15 years ago)
Author:
vboxsync
Message:

PDM,*: Redid the PDM structure versions. Check the instance and helper versions in every device and driver constructor.

Location:
trunk/src/VBox/Devices/Network
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DevE1000.cpp

    r25986 r26001  
    47244724}
    47254725
     4726/* -=-=-=-=- PDMDEVREG -=-=-=-=- */
     4727
     4728#ifdef VBOX_DYNAMIC_NET_ATTACH
     4729
     4730/**
     4731 * Detach notification.
     4732 *
     4733 * One port on the network card has been disconnected from the network.
     4734 *
     4735 * @param   pDevIns     The device instance.
     4736 * @param   iLUN        The logical unit which is being detached.
     4737 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
     4738 */
     4739static DECLCALLBACK(void) e1kDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
     4740{
     4741    E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
     4742    Log(("%s e1kDetach:\n", INSTANCE(pState)));
     4743
     4744    AssertLogRelReturnVoid(iLUN == 0);
     4745
     4746    PDMCritSectEnter(&pState->cs, VERR_SEM_BUSY);
     4747
     4748    /** @todo: r=pritesh still need to check if i missed
     4749     * to clean something in this function
     4750     */
     4751
     4752    /*
     4753     * Zero some important members.
     4754     */
     4755    pState->pDrvBase = NULL;
     4756    pState->pDrv = NULL;
     4757
     4758    PDMCritSectLeave(&pState->cs);
     4759}
     4760
     4761
     4762/**
     4763 * Attach the Network attachment.
     4764 *
     4765 * One port on the network card has been connected to a network.
     4766 *
     4767 * @returns VBox status code.
     4768 * @param   pDevIns     The device instance.
     4769 * @param   iLUN        The logical unit which is being attached.
     4770 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
     4771 *
     4772 * @remarks This code path is not used during construction.
     4773 */
     4774static DECLCALLBACK(int) e1kAttach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
     4775{
     4776    E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
     4777    LogFlow(("%s e1kAttach:\n",  INSTANCE(pState)));
     4778
     4779    AssertLogRelReturn(iLUN == 0, VERR_PDM_NO_SUCH_LUN);
     4780
     4781    PDMCritSectEnter(&pState->cs, VERR_SEM_BUSY);
     4782
     4783    /*
     4784     * Attach the driver.
     4785     */
     4786    int rc = PDMDevHlpDriverAttach(pDevIns, 0, &pState->IBase, &pState->pDrvBase, "Network Port");
     4787    if (RT_SUCCESS(rc))
     4788    {
     4789        if (rc == VINF_NAT_DNS)
     4790        {
     4791#ifdef RT_OS_LINUX
     4792            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
     4793                                       N_("A Domain Name Server (DNS) for NAT networking could not be determined. Please check your /etc/resolv.conf for <tt>nameserver</tt> entries. Either add one manually (<i>man resolv.conf</i>) or ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
     4794#else
     4795            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
     4796                                       N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
     4797#endif
     4798        }
     4799        pState->pDrv = PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMINETWORKCONNECTOR);
     4800        AssertMsgStmt(pState->pDrv, ("Failed to obtain the PDMINETWORKCONNECTOR interface!\n"),
     4801                      rc = VERR_PDM_MISSING_INTERFACE_BELOW);
     4802    }
     4803    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
     4804        Log(("%s No attached driver!\n", INSTANCE(pState)));
     4805
     4806
     4807    /*
     4808     * Temporary set the link down if it was up so that the guest
     4809     * will know that we have change the configuration of the
     4810     * network card
     4811     */
     4812    if ((STATUS & STATUS_LU) && RT_SUCCESS(rc))
     4813    {
     4814        STATUS &= ~STATUS_LU;
     4815        Phy::setLinkStatus(&pState->phy, false);
     4816        e1kRaiseInterrupt(pState, VERR_SEM_BUSY, ICR_LSC);
     4817        /* Restore the link back in 5 second. */
     4818        e1kArmTimer(pState, pState->pLUTimer, 5000000);
     4819    }
     4820
     4821    PDMCritSectLeave(&pState->cs);
     4822    return rc;
     4823
     4824}
     4825
     4826#endif /* VBOX_DYNAMIC_NET_ATTACH */
     4827
     4828/**
     4829 * @copydoc FNPDMDEVPOWEROFF
     4830 */
     4831static DECLCALLBACK(void) e1kPowerOff(PPDMDEVINS pDevIns)
     4832{
     4833    /* Poke thread waiting for buffer space. */
     4834    e1kWakeupReceive(pDevIns);
     4835}
     4836
     4837/**
     4838 * @copydoc FNPDMDEVSUSPEND
     4839 */
     4840static DECLCALLBACK(void) e1kSuspend(PPDMDEVINS pDevIns)
     4841{
     4842    /* Poke thread waiting for buffer space. */
     4843    e1kWakeupReceive(pDevIns);
     4844}
     4845
     4846/**
     4847 * Device relocation callback.
     4848 *
     4849 * When this callback is called the device instance data, and if the
     4850 * device have a GC component, is being relocated, or/and the selectors
     4851 * have been changed. The device must use the chance to perform the
     4852 * necessary pointer relocations and data updates.
     4853 *
     4854 * Before the GC code is executed the first time, this function will be
     4855 * called with a 0 delta so GC pointer calculations can be one in one place.
     4856 *
     4857 * @param   pDevIns     Pointer to the device instance.
     4858 * @param   offDelta    The relocation delta relative to the old location.
     4859 *
     4860 * @remark  A relocation CANNOT fail.
     4861 */
     4862static DECLCALLBACK(void) e1kRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
     4863{
     4864    E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
     4865    pState->pDevInsRC     = PDMDEVINS_2_RCPTR(pDevIns);
     4866    pState->pTxQueueRC    = PDMQueueRCPtr(pState->pTxQueueR3);
     4867    pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
     4868#ifdef E1K_USE_RX_TIMERS
     4869    pState->pRIDTimerRC   = TMTimerRCPtr(pState->pRIDTimerR3);
     4870    pState->pRADTimerRC   = TMTimerRCPtr(pState->pRADTimerR3);
     4871#endif /* E1K_USE_RX_TIMERS */
     4872#ifdef E1K_USE_TX_TIMERS
     4873    pState->pTIDTimerRC   = TMTimerRCPtr(pState->pTIDTimerR3);
     4874# ifndef E1K_NO_TAD
     4875    pState->pTADTimerRC   = TMTimerRCPtr(pState->pTADTimerR3);
     4876# endif /* E1K_NO_TAD */
     4877#endif /* E1K_USE_TX_TIMERS */
     4878    pState->pIntTimerRC   = TMTimerRCPtr(pState->pIntTimerR3);
     4879}
     4880
     4881/**
     4882 * Destruct a device instance.
     4883 *
     4884 * We need to free non-VM resources only.
     4885 *
     4886 * @returns VBox status.
     4887 * @param   pDevIns     The device instance data.
     4888 * @thread  EMT
     4889 */
     4890static DECLCALLBACK(int) e1kDestruct(PPDMDEVINS pDevIns)
     4891{
     4892    E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
     4893    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
     4894
     4895    e1kDumpState(pState);
     4896    E1kLog(("%s Destroying instance\n", INSTANCE(pState)));
     4897    if (PDMCritSectIsInitialized(&pState->cs))
     4898    {
     4899        if (pState->hEventMoreRxDescAvail != NIL_RTSEMEVENT)
     4900        {
     4901            RTSemEventSignal(pState->hEventMoreRxDescAvail);
     4902            RTSemEventDestroy(pState->hEventMoreRxDescAvail);
     4903            pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
     4904        }
     4905        if (pState->hTxSem != NIL_RTSEMEVENT)
     4906        {
     4907            RTSemEventDestroy(pState->hTxSem);
     4908            pState->hTxSem = NIL_RTSEMEVENT;
     4909        }
     4910#ifndef E1K_GLOBAL_MUTEX
     4911        PDMR3CritSectDelete(&pState->csRx);
     4912        //PDMR3CritSectDelete(&pState->csTx);
     4913#endif
     4914        PDMR3CritSectDelete(&pState->cs);
     4915    }
     4916    return VINF_SUCCESS;
     4917}
     4918
    47264919/**
    47274920 * Sets 8-bit register in PCI configuration space.
     
    48475040    E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
    48485041    int       rc;
     5042    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    48495043
    48505044    /* Init handles and log related stuff. */
     
    51295323
    51305324    return VINF_SUCCESS;
    5131 }
    5132 
    5133 /**
    5134  * Destruct a device instance.
    5135  *
    5136  * We need to free non-VM resources only.
    5137  *
    5138  * @returns VBox status.
    5139  * @param   pDevIns     The device instance data.
    5140  * @thread  EMT
    5141  */
    5142 static DECLCALLBACK(int) e1kDestruct(PPDMDEVINS pDevIns)
    5143 {
    5144     E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
    5145 
    5146     e1kDumpState(pState);
    5147     E1kLog(("%s Destroying instance\n", INSTANCE(pState)));
    5148     if (PDMCritSectIsInitialized(&pState->cs))
    5149     {
    5150         if (pState->hEventMoreRxDescAvail != NIL_RTSEMEVENT)
    5151         {
    5152             RTSemEventSignal(pState->hEventMoreRxDescAvail);
    5153             RTSemEventDestroy(pState->hEventMoreRxDescAvail);
    5154             pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
    5155         }
    5156         if (pState->hTxSem != NIL_RTSEMEVENT)
    5157         {
    5158             RTSemEventDestroy(pState->hTxSem);
    5159             pState->hTxSem = NIL_RTSEMEVENT;
    5160         }
    5161 #ifndef E1K_GLOBAL_MUTEX
    5162         PDMR3CritSectDelete(&pState->csRx);
    5163         //PDMR3CritSectDelete(&pState->csTx);
    5164 #endif
    5165         PDMR3CritSectDelete(&pState->cs);
    5166     }
    5167     return VINF_SUCCESS;
    5168 }
    5169 
    5170 /**
    5171  * Device relocation callback.
    5172  *
    5173  * When this callback is called the device instance data, and if the
    5174  * device have a GC component, is being relocated, or/and the selectors
    5175  * have been changed. The device must use the chance to perform the
    5176  * necessary pointer relocations and data updates.
    5177  *
    5178  * Before the GC code is executed the first time, this function will be
    5179  * called with a 0 delta so GC pointer calculations can be one in one place.
    5180  *
    5181  * @param   pDevIns     Pointer to the device instance.
    5182  * @param   offDelta    The relocation delta relative to the old location.
    5183  *
    5184  * @remark  A relocation CANNOT fail.
    5185  */
    5186 static DECLCALLBACK(void) e1kRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
    5187 {
    5188     E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
    5189     pState->pDevInsRC     = PDMDEVINS_2_RCPTR(pDevIns);
    5190     pState->pTxQueueRC    = PDMQueueRCPtr(pState->pTxQueueR3);
    5191     pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
    5192 #ifdef E1K_USE_RX_TIMERS
    5193     pState->pRIDTimerRC   = TMTimerRCPtr(pState->pRIDTimerR3);
    5194     pState->pRADTimerRC   = TMTimerRCPtr(pState->pRADTimerR3);
    5195 #endif /* E1K_USE_RX_TIMERS */
    5196 #ifdef E1K_USE_TX_TIMERS
    5197     pState->pTIDTimerRC   = TMTimerRCPtr(pState->pTIDTimerR3);
    5198 # ifndef E1K_NO_TAD
    5199     pState->pTADTimerRC   = TMTimerRCPtr(pState->pTADTimerR3);
    5200 # endif /* E1K_NO_TAD */
    5201 #endif /* E1K_USE_TX_TIMERS */
    5202     pState->pIntTimerRC   = TMTimerRCPtr(pState->pIntTimerR3);
    5203 }
    5204 
    5205 /**
    5206  * @copydoc FNPDMDEVSUSPEND
    5207  */
    5208 static DECLCALLBACK(void) e1kSuspend(PPDMDEVINS pDevIns)
    5209 {
    5210     /* Poke thread waiting for buffer space. */
    5211     e1kWakeupReceive(pDevIns);
    5212 }
    5213 
    5214 
    5215 #ifdef VBOX_DYNAMIC_NET_ATTACH
    5216 /**
    5217  * Detach notification.
    5218  *
    5219  * One port on the network card has been disconnected from the network.
    5220  *
    5221  * @param   pDevIns     The device instance.
    5222  * @param   iLUN        The logical unit which is being detached.
    5223  * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    5224  */
    5225 static DECLCALLBACK(void) e1kDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
    5226 {
    5227     E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
    5228     Log(("%s e1kDetach:\n", INSTANCE(pState)));
    5229 
    5230     AssertLogRelReturnVoid(iLUN == 0);
    5231 
    5232     PDMCritSectEnter(&pState->cs, VERR_SEM_BUSY);
    5233 
    5234     /** @todo: r=pritesh still need to check if i missed
    5235      * to clean something in this function
    5236      */
    5237 
    5238     /*
    5239      * Zero some important members.
    5240      */
    5241     pState->pDrvBase = NULL;
    5242     pState->pDrv = NULL;
    5243 
    5244     PDMCritSectLeave(&pState->cs);
    5245 }
    5246 
    5247 
    5248 /**
    5249  * Attach the Network attachment.
    5250  *
    5251  * One port on the network card has been connected to a network.
    5252  *
    5253  * @returns VBox status code.
    5254  * @param   pDevIns     The device instance.
    5255  * @param   iLUN        The logical unit which is being attached.
    5256  * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    5257  *
    5258  * @remarks This code path is not used during construction.
    5259  */
    5260 static DECLCALLBACK(int) e1kAttach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
    5261 {
    5262     E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
    5263     LogFlow(("%s e1kAttach:\n",  INSTANCE(pState)));
    5264 
    5265     AssertLogRelReturn(iLUN == 0, VERR_PDM_NO_SUCH_LUN);
    5266 
    5267     PDMCritSectEnter(&pState->cs, VERR_SEM_BUSY);
    5268 
    5269     /*
    5270      * Attach the driver.
    5271      */
    5272     int rc = PDMDevHlpDriverAttach(pDevIns, 0, &pState->IBase, &pState->pDrvBase, "Network Port");
    5273     if (RT_SUCCESS(rc))
    5274     {
    5275         if (rc == VINF_NAT_DNS)
    5276         {
    5277 #ifdef RT_OS_LINUX
    5278             PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
    5279                                        N_("A Domain Name Server (DNS) for NAT networking could not be determined. Please check your /etc/resolv.conf for <tt>nameserver</tt> entries. Either add one manually (<i>man resolv.conf</i>) or ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
    5280 #else
    5281             PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
    5282                                        N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
    5283 #endif
    5284         }
    5285         pState->pDrv = PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMINETWORKCONNECTOR);
    5286         AssertMsgStmt(pState->pDrv, ("Failed to obtain the PDMINETWORKCONNECTOR interface!\n"),
    5287                       rc = VERR_PDM_MISSING_INTERFACE_BELOW);
    5288     }
    5289     else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
    5290         Log(("%s No attached driver!\n", INSTANCE(pState)));
    5291 
    5292 
    5293     /*
    5294      * Temporary set the link down if it was up so that the guest
    5295      * will know that we have change the configuration of the
    5296      * network card
    5297      */
    5298     if ((STATUS & STATUS_LU) && RT_SUCCESS(rc))
    5299     {
    5300         STATUS &= ~STATUS_LU;
    5301         Phy::setLinkStatus(&pState->phy, false);
    5302         e1kRaiseInterrupt(pState, VERR_SEM_BUSY, ICR_LSC);
    5303         /* Restore the link back in 5 second. */
    5304         e1kArmTimer(pState, pState->pLUTimer, 5000000);
    5305     }
    5306 
    5307     PDMCritSectLeave(&pState->cs);
    5308     return rc;
    5309 
    5310 }
    5311 #endif /* VBOX_DYNAMIC_NET_ATTACH */
    5312 
    5313 
    5314 /**
    5315  * @copydoc FNPDMDEVPOWEROFF
    5316  */
    5317 static DECLCALLBACK(void) e1kPowerOff(PPDMDEVINS pDevIns)
    5318 {
    5319     /* Poke thread waiting for buffer space. */
    5320     e1kWakeupReceive(pDevIns);
    53215325}
    53225326
  • trunk/src/VBox/Devices/Network/DevINIP.cpp

    r25986 r26001  
    389389}
    390390
     391/* -=-=-=-=- PDMIBASE -=-=-=-=- */
    391392
    392393/**
     
    400401    PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKPORT, &pThis->INetworkPort);
    401402    return NULL;
     403}
     404
     405/* -=-=-=-=- PDMDEVREG -=-=-=-=- */
     406
     407/**
     408 * Destruct a device instance.
     409 *
     410 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
     411 * resources can be freed correctly.
     412 *
     413 * @returns VBox status.
     414 * @param   pDevIns     The device instance data.
     415 */
     416static DECLCALLBACK(int) devINIPDestruct(PPDMDEVINS pDevIns)
     417{
     418    PDEVINTNETIP pThis = PDMINS_2_DATA(pDevIns, PDEVINTNETIP);
     419
     420    LogFlow(("%s: pDevIns=%p\n", __FUNCTION__, pDevIns));
     421    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
     422
     423    if (g_pDevINIPData != NULL)
     424    {
     425        netif_set_down(&pThis->IntNetIF);
     426        netif_remove(&pThis->IntNetIF);
     427        tcpip_terminate();
     428        lwip_sys_sem_wait(pThis->LWIPTcpInitSem);
     429        lwip_sys_sem_free(pThis->LWIPTcpInitSem);
     430    }
     431
     432    if (pThis->pszIP)
     433        MMR3HeapFree(pThis->pszIP);
     434    if (pThis->pszNetmask)
     435        MMR3HeapFree(pThis->pszNetmask);
     436    if (pThis->pszGateway)
     437        MMR3HeapFree(pThis->pszGateway);
     438
     439    LogFlow(("%s: success\n", __FUNCTION__));
     440    return VINF_SUCCESS;
    402441}
    403442
     
    426465
    427466    Assert(iInstance == 0);
     467    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    428468
    429469    /*
     
    631671
    632672/**
    633  * Destruct a device instance.
    634  *
    635  * Most VM resources are freed by the VM. This callback is provided so that any non-VM
    636  * resources can be freed correctly.
    637  *
    638  * @returns VBox status.
    639  * @param   pDevIns     The device instance data.
    640  */
    641 static DECLCALLBACK(int) devINIPDestruct(PPDMDEVINS pDevIns)
    642 {
    643     PDEVINTNETIP pThis = PDMINS_2_DATA(pDevIns, PDEVINTNETIP);
    644 
    645     LogFlow(("%s: pDevIns=%p\n", __FUNCTION__, pDevIns));
    646 
    647     if (g_pDevINIPData != NULL)
    648     {
    649         netif_set_down(&pThis->IntNetIF);
    650         netif_remove(&pThis->IntNetIF);
    651         tcpip_terminate();
    652         lwip_sys_sem_wait(pThis->LWIPTcpInitSem);
    653         lwip_sys_sem_free(pThis->LWIPTcpInitSem);
    654     }
    655 
    656     if (pThis->pszIP)
    657         MMR3HeapFree(pThis->pszIP);
    658     if (pThis->pszNetmask)
    659         MMR3HeapFree(pThis->pszNetmask);
    660     if (pThis->pszGateway)
    661         MMR3HeapFree(pThis->pszGateway);
    662 
    663     LogFlow(("%s: success\n", __FUNCTION__));
    664     return VINF_SUCCESS;
    665 }
    666 
    667 
    668 /**
    669673 * Query whether lwIP is initialized or not. Since there is only a single
    670674 * instance of this device ever for a VM, it can be a global function.
  • trunk/src/VBox/Devices/Network/DevPCNet.cpp

    r25986 r26001  
    49064906{
    49074907    PCNetState *pThis = PDMINS_2_DATA(pDevIns, PCNetState *);
     4908    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
    49084909
    49094910    if (PDMCritSectIsInitialized(&pThis->CritSect))
     
    49524953    Assert((iInstance >= 0) && (iInstance < 8));
    49534954
     4955    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    49544956    Assert(RT_ELEMENTS(pThis->aBCR) == BCR_MAX_RAP);
    49554957    Assert(RT_ELEMENTS(pThis->aMII) == MII_MAX_REG);
  • trunk/src/VBox/Devices/Network/DevVirtioNet.cpp

    r25986 r26001  
    14341434}
    14351435
    1436 /**
    1437  * Construct a device instance for a VM.
    1438  *
    1439  * @returns VBox status.
    1440  * @param   pDevIns     The device instance data.
    1441  *                      If the registration structure is needed, pDevIns->pDevReg points to it.
    1442  * @param   iInstance   Instance number. Use this to figure out which registers and such to use.
    1443  *                      The device number is also found in pDevIns->iInstance, but since it's
    1444  *                      likely to be freqently used PDM passes it as parameter.
    1445  * @param   pCfgHandle  Configuration node handle for the device. Use this to obtain the configuration
    1446  *                      of the device instance. It's also found in pDevIns->pCfgHandle, but like
    1447  *                      iInstance it's expected to be used a bit in this function.
    1448  * @thread  EMT
    1449  */
    1450 static DECLCALLBACK(int) vnetConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
    1451 {
    1452     VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
    1453     int        rc;
    1454 
    1455     /* Initialize PCI part first. */
    1456     pState->VPCI.IBase.pfnQueryInterface    = vnetQueryInterface;
    1457     rc = vpciConstruct(pDevIns, &pState->VPCI, iInstance,
    1458                        VNET_NAME_FMT, VNET_PCI_SUBSYSTEM_ID,
    1459                        VNET_PCI_CLASS, VNET_N_QUEUES);
    1460     pState->pRxQueue  = vpciAddQueue(&pState->VPCI, 256, vnetQueueReceive,  "RX ");
    1461     pState->pTxQueue  = vpciAddQueue(&pState->VPCI, 256, vnetQueueTransmit, "TX ");
    1462     pState->pCtlQueue = vpciAddQueue(&pState->VPCI, 16,  vnetQueueControl,  "CTL");
    1463 
    1464     Log(("%s Constructing new instance\n", INSTANCE(pState)));
    1465 
    1466     pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
    1467 
    1468     /*
    1469      * Validate configuration.
    1470      */
    1471     if (!CFGMR3AreValuesValid(pCfgHandle, "MAC\0" "CableConnected\0" "LineSpeed\0"))
    1472                     return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
    1473                                             N_("Invalid configuration for VirtioNet device"));
    1474 
    1475     /* Get config params */
    1476     rc = CFGMR3QueryBytes(pCfgHandle, "MAC", pState->macConfigured.au8,
    1477                           sizeof(pState->macConfigured));
    1478     if (RT_FAILURE(rc))
    1479         return PDMDEV_SET_ERROR(pDevIns, rc,
    1480                                 N_("Configuration error: Failed to get MAC address"));
    1481     rc = CFGMR3QueryBool(pCfgHandle, "CableConnected", &pState->fCableConnected);
    1482     if (RT_FAILURE(rc))
    1483         return PDMDEV_SET_ERROR(pDevIns, rc,
    1484                                 N_("Configuration error: Failed to get the value of 'CableConnected'"));
    1485 
    1486     /* Initialize PCI config space */
    1487     memcpy(pState->config.mac.au8, pState->macConfigured.au8, sizeof(pState->config.mac.au8));
    1488     pState->config.uStatus = 0;
    1489 
    1490     /* Initialize state structure */
    1491     pState->u32PktNo     = 1;
    1492 
    1493     /* Interfaces */
    1494     pState->INetworkPort.pfnWaitReceiveAvail = vnetWaitReceiveAvail;
    1495     pState->INetworkPort.pfnReceive          = vnetReceive;
    1496     pState->INetworkConfig.pfnGetMac         = vnetGetMac;
    1497     pState->INetworkConfig.pfnGetLinkState   = vnetGetLinkState;
    1498     pState->INetworkConfig.pfnSetLinkState   = vnetSetLinkState;
    1499 
    1500     pState->pTxBuf = (uint8_t *)RTMemAllocZ(VNET_MAX_FRAME_SIZE);
    1501     AssertMsgReturn(pState->pTxBuf,
    1502                     ("Cannot allocate TX buffer for virtio-net device\n"), VERR_NO_MEMORY);
    1503 
    1504     /* Initialize critical section. */
    1505     // char szTmp[sizeof(pState->VPCI.szInstance) + 2];
    1506     // RTStrPrintf(szTmp, sizeof(szTmp), "%sRX", pState->VPCI.szInstance);
    1507     // rc = PDMDevHlpCritSectInit(pDevIns, &pState->csRx, szTmp);
    1508     // if (RT_FAILURE(rc))
    1509     //     return rc;
    1510 
    1511     /* Map our ports to IO space. */
    1512     rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0,
    1513                                       VPCI_CONFIG + sizeof(VNetPCIConfig),
    1514                                       PCI_ADDRESS_SPACE_IO, vnetMap);
    1515     if (RT_FAILURE(rc))
    1516         return rc;
    1517 
    1518 
    1519     /* Register save/restore state handlers. */
    1520     rc = PDMDevHlpSSMRegisterEx(pDevIns, VIRTIO_SAVEDSTATE_VERSION, sizeof(VNETSTATE), NULL,
    1521                                 NULL,         vnetLiveExec, NULL,
    1522                                 vnetSavePrep, vnetSaveExec, NULL,
    1523                                 vnetLoadPrep, vnetLoadExec, vnetLoadDone);
    1524     if (RT_FAILURE(rc))
    1525         return rc;
    1526 
    1527     /* Create the RX notifier signaller. */
    1528     rc = PDMDevHlpPDMQueueCreate(pDevIns, sizeof(PDMQUEUEITEMCORE), 1, 0,
    1529                                  vnetCanRxQueueConsumer, true, "VNet-Rcv", &pState->pCanRxQueueR3);
    1530     if (RT_FAILURE(rc))
    1531         return rc;
    1532     pState->pCanRxQueueR0 = PDMQueueR0Ptr(pState->pCanRxQueueR3);
    1533     pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
    1534 
    1535     /* Create Link Up Timer */
    1536     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetLinkUpTimer, pState,
    1537                                 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
    1538                                 "VirtioNet Link Up Timer", &pState->pLinkUpTimer);
    1539     if (RT_FAILURE(rc))
    1540         return rc;
    1541 
    1542 #ifdef VNET_TX_DELAY
    1543     /* Create Transmit Delay Timer */
    1544     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetTxTimer, pState,
    1545                                 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
    1546                                 "VirtioNet TX Delay Timer", &pState->pTxTimerR3);
    1547     if (RT_FAILURE(rc))
    1548         return rc;
    1549     pState->pTxTimerR0 = TMTimerR0Ptr(pState->pTxTimerR3);
    1550     pState->pTxTimerRC = TMTimerRCPtr(pState->pTxTimerR3);
    1551 
    1552     pState->u32i = pState->u32AvgDiff = pState->u32MaxDiff = 0;
    1553     pState->u32MinDiff = ~0;
    1554 #endif /* VNET_TX_DELAY */
    1555 
    1556     rc = PDMDevHlpDriverAttach(pDevIns, 0, &pState->VPCI.IBase, &pState->pDrvBase, "Network Port");
    1557     if (RT_SUCCESS(rc))
    1558     {
    1559         if (rc == VINF_NAT_DNS)
    1560         {
    1561             PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
    1562                                        N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
    1563         }
    1564         pState->pDrv = PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMINETWORKCONNECTOR);
    1565         AssertMsgReturn(pState->pDrv, ("Failed to obtain the PDMINETWORKCONNECTOR interface!\n"),
    1566                         VERR_PDM_MISSING_INTERFACE_BELOW);
    1567     }
    1568     else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
    1569     {
    1570         Log(("%s This adapter is not attached to any network!\n", INSTANCE(pState)));
    1571     }
    1572     else
    1573         return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to attach the network LUN"));
    1574 
    1575     rc = RTSemEventCreate(&pState->hEventMoreRxDescAvail);
    1576     if (RT_FAILURE(rc))
    1577         return rc;
    1578 
    1579     vnetReset(pState);
    1580 
    1581     PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveBytes,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,          "Amount of data received",            "/Devices/VNet%d/ReceiveBytes", iInstance);
    1582     PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitBytes,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,          "Amount of data transmitted",         "/Devices/VNet%d/TransmitBytes", iInstance);
    1583 #if defined(VBOX_WITH_STATISTICS)
    1584     PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceive,            STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive",                  "/Devices/VNet%d/Receive/Total", iInstance);
    1585     PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveStore,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive storing",          "/Devices/VNet%d/Receive/Store", iInstance);
    1586     PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatRxOverflow,         STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, "Profiling RX overflows",        "/Devices/VNet%d/RxOverflow", iInstance);
    1587     PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatRxOverflowWakeup,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of RX overflow wakeups",          "/Devices/VNet%d/RxOverflowWakeup", iInstance);
    1588     PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmit,           STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling transmits in HC",          "/Devices/VNet%d/Transmit/Total", iInstance);
    1589     PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitSend,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling send transmit in HC",      "/Devices/VNet%d/Transmit/Send", iInstance);
    1590 #endif /* VBOX_WITH_STATISTICS */
    1591 
    1592     return VINF_SUCCESS;
    1593 }
    1594 
    1595 /**
    1596  * Destruct a device instance.
    1597  *
    1598  * We need to free non-VM resources only.
    1599  *
    1600  * @returns VBox status.
    1601  * @param   pDevIns     The device instance data.
    1602  * @thread  EMT
    1603  */
    1604 static DECLCALLBACK(int) vnetDestruct(PPDMDEVINS pDevIns)
    1605 {
    1606     VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
    1607 
    1608     LogRel(("TxTimer stats (avg/min/max): %7d usec %7d usec %7d usec\n",
    1609             pState->u32AvgDiff, pState->u32MinDiff, pState->u32MaxDiff));
    1610     Log(("%s Destroying instance\n", INSTANCE(pState)));
    1611     if (pState->hEventMoreRxDescAvail != NIL_RTSEMEVENT)
    1612     {
    1613         RTSemEventSignal(pState->hEventMoreRxDescAvail);
    1614         RTSemEventDestroy(pState->hEventMoreRxDescAvail);
    1615         pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
    1616     }
    1617 
    1618     if (pState->pTxBuf)
    1619     {
    1620         RTMemFree(pState->pTxBuf);
    1621         pState->pTxBuf = NULL;
    1622     }
    1623     // if (PDMCritSectIsInitialized(&pState->csRx))
    1624     //     PDMR3CritSectDelete(&pState->csRx);
    1625 
    1626     return vpciDestruct(&pState->VPCI);
    1627 }
    1628 
    1629 /**
    1630  * Device relocation callback.
    1631  *
    1632  * When this callback is called the device instance data, and if the
    1633  * device have a GC component, is being relocated, or/and the selectors
    1634  * have been changed. The device must use the chance to perform the
    1635  * necessary pointer relocations and data updates.
    1636  *
    1637  * Before the GC code is executed the first time, this function will be
    1638  * called with a 0 delta so GC pointer calculations can be one in one place.
    1639  *
    1640  * @param   pDevIns     Pointer to the device instance.
    1641  * @param   offDelta    The relocation delta relative to the old location.
    1642  *
    1643  * @remark  A relocation CANNOT fail.
    1644  */
    1645 static DECLCALLBACK(void) vnetRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
    1646 {
    1647     VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
    1648     vpciRelocate(pDevIns, offDelta);
    1649     pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
    1650 #ifdef VNET_TX_DELAY
    1651     pState->pTxTimerRC    = TMTimerRCPtr(pState->pTxTimerR3);
    1652 #endif /* VNET_TX_DELAY */
    1653     // TBD
    1654 }
    1655 
    1656 /**
    1657  * @copydoc FNPDMDEVSUSPEND
    1658  */
    1659 static DECLCALLBACK(void) vnetSuspend(PPDMDEVINS pDevIns)
    1660 {
    1661     /* Poke thread waiting for buffer space. */
    1662     vnetWakeupReceive(pDevIns);
    1663 }
    1664 
     1436/* -=-=-=-=- PDMDEVREG -=-=-=-=- */
    16651437
    16661438#ifdef VBOX_DYNAMIC_NET_ATTACH
     1439
    16671440/**
    16681441 * Detach notification.
     
    17601533
    17611534}
     1535
    17621536#endif /* VBOX_DYNAMIC_NET_ATTACH */
    17631537
    1764 
    1765 /**
    1766  * @copydoc FNPDMDEVPOWEROFF
    1767  */
    1768 static DECLCALLBACK(void) vnetPowerOff(PPDMDEVINS pDevIns)
     1538/**
     1539 * @copydoc FNPDMDEVSUSPEND
     1540 */
     1541static DECLCALLBACK(void) vnetSuspend(PPDMDEVINS pDevIns)
    17691542{
    17701543    /* Poke thread waiting for buffer space. */
    17711544    vnetWakeupReceive(pDevIns);
     1545}
     1546
     1547/**
     1548 * @copydoc FNPDMDEVPOWEROFF
     1549 */
     1550static DECLCALLBACK(void) vnetPowerOff(PPDMDEVINS pDevIns)
     1551{
     1552    /* Poke thread waiting for buffer space. */
     1553    vnetWakeupReceive(pDevIns);
     1554}
     1555
     1556/**
     1557 * Device relocation callback.
     1558 *
     1559 * When this callback is called the device instance data, and if the
     1560 * device have a GC component, is being relocated, or/and the selectors
     1561 * have been changed. The device must use the chance to perform the
     1562 * necessary pointer relocations and data updates.
     1563 *
     1564 * Before the GC code is executed the first time, this function will be
     1565 * called with a 0 delta so GC pointer calculations can be one in one place.
     1566 *
     1567 * @param   pDevIns     Pointer to the device instance.
     1568 * @param   offDelta    The relocation delta relative to the old location.
     1569 *
     1570 * @remark  A relocation CANNOT fail.
     1571 */
     1572static DECLCALLBACK(void) vnetRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
     1573{
     1574    VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
     1575    vpciRelocate(pDevIns, offDelta);
     1576    pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
     1577#ifdef VNET_TX_DELAY
     1578    pState->pTxTimerRC    = TMTimerRCPtr(pState->pTxTimerR3);
     1579#endif /* VNET_TX_DELAY */
     1580    // TBD
     1581}
     1582
     1583/**
     1584 * Destruct a device instance.
     1585 *
     1586 * We need to free non-VM resources only.
     1587 *
     1588 * @returns VBox status.
     1589 * @param   pDevIns     The device instance data.
     1590 * @thread  EMT
     1591 */
     1592static DECLCALLBACK(int) vnetDestruct(PPDMDEVINS pDevIns)
     1593{
     1594    VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
     1595    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
     1596
     1597    LogRel(("TxTimer stats (avg/min/max): %7d usec %7d usec %7d usec\n",
     1598            pState->u32AvgDiff, pState->u32MinDiff, pState->u32MaxDiff));
     1599    Log(("%s Destroying instance\n", INSTANCE(pState)));
     1600    if (pState->hEventMoreRxDescAvail != NIL_RTSEMEVENT)
     1601    {
     1602        RTSemEventSignal(pState->hEventMoreRxDescAvail);
     1603        RTSemEventDestroy(pState->hEventMoreRxDescAvail);
     1604        pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
     1605    }
     1606
     1607    if (pState->pTxBuf)
     1608    {
     1609        RTMemFree(pState->pTxBuf);
     1610        pState->pTxBuf = NULL;
     1611    }
     1612    // if (PDMCritSectIsInitialized(&pState->csRx))
     1613    //     PDMR3CritSectDelete(&pState->csRx);
     1614
     1615    return vpciDestruct(&pState->VPCI);
     1616}
     1617
     1618/**
     1619 * Construct a device instance for a VM.
     1620 *
     1621 * @returns VBox status.
     1622 * @param   pDevIns     The device instance data.
     1623 *                      If the registration structure is needed, pDevIns->pDevReg points to it.
     1624 * @param   iInstance   Instance number. Use this to figure out which registers and such to use.
     1625 *                      The device number is also found in pDevIns->iInstance, but since it's
     1626 *                      likely to be freqently used PDM passes it as parameter.
     1627 * @param   pCfgHandle  Configuration node handle for the device. Use this to obtain the configuration
     1628 *                      of the device instance. It's also found in pDevIns->pCfgHandle, but like
     1629 *                      iInstance it's expected to be used a bit in this function.
     1630 * @thread  EMT
     1631 */
     1632static DECLCALLBACK(int) vnetConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
     1633{
     1634    VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
     1635    int        rc;
     1636    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
     1637
     1638    /* Initialize PCI part first. */
     1639    pState->VPCI.IBase.pfnQueryInterface    = vnetQueryInterface;
     1640    rc = vpciConstruct(pDevIns, &pState->VPCI, iInstance,
     1641                       VNET_NAME_FMT, VNET_PCI_SUBSYSTEM_ID,
     1642                       VNET_PCI_CLASS, VNET_N_QUEUES);
     1643    pState->pRxQueue  = vpciAddQueue(&pState->VPCI, 256, vnetQueueReceive,  "RX ");
     1644    pState->pTxQueue  = vpciAddQueue(&pState->VPCI, 256, vnetQueueTransmit, "TX ");
     1645    pState->pCtlQueue = vpciAddQueue(&pState->VPCI, 16,  vnetQueueControl,  "CTL");
     1646
     1647    Log(("%s Constructing new instance\n", INSTANCE(pState)));
     1648
     1649    pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
     1650
     1651    /*
     1652     * Validate configuration.
     1653     */
     1654    if (!CFGMR3AreValuesValid(pCfgHandle, "MAC\0" "CableConnected\0" "LineSpeed\0"))
     1655                    return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
     1656                                            N_("Invalid configuration for VirtioNet device"));
     1657
     1658    /* Get config params */
     1659    rc = CFGMR3QueryBytes(pCfgHandle, "MAC", pState->macConfigured.au8,
     1660                          sizeof(pState->macConfigured));
     1661    if (RT_FAILURE(rc))
     1662        return PDMDEV_SET_ERROR(pDevIns, rc,
     1663                                N_("Configuration error: Failed to get MAC address"));
     1664    rc = CFGMR3QueryBool(pCfgHandle, "CableConnected", &pState->fCableConnected);
     1665    if (RT_FAILURE(rc))
     1666        return PDMDEV_SET_ERROR(pDevIns, rc,
     1667                                N_("Configuration error: Failed to get the value of 'CableConnected'"));
     1668
     1669    /* Initialize PCI config space */
     1670    memcpy(pState->config.mac.au8, pState->macConfigured.au8, sizeof(pState->config.mac.au8));
     1671    pState->config.uStatus = 0;
     1672
     1673    /* Initialize state structure */
     1674    pState->u32PktNo     = 1;
     1675
     1676    /* Interfaces */
     1677    pState->INetworkPort.pfnWaitReceiveAvail = vnetWaitReceiveAvail;
     1678    pState->INetworkPort.pfnReceive          = vnetReceive;
     1679    pState->INetworkConfig.pfnGetMac         = vnetGetMac;
     1680    pState->INetworkConfig.pfnGetLinkState   = vnetGetLinkState;
     1681    pState->INetworkConfig.pfnSetLinkState   = vnetSetLinkState;
     1682
     1683    pState->pTxBuf = (uint8_t *)RTMemAllocZ(VNET_MAX_FRAME_SIZE);
     1684    AssertMsgReturn(pState->pTxBuf,
     1685                    ("Cannot allocate TX buffer for virtio-net device\n"), VERR_NO_MEMORY);
     1686
     1687    /* Initialize critical section. */
     1688    // char szTmp[sizeof(pState->VPCI.szInstance) + 2];
     1689    // RTStrPrintf(szTmp, sizeof(szTmp), "%sRX", pState->VPCI.szInstance);
     1690    // rc = PDMDevHlpCritSectInit(pDevIns, &pState->csRx, szTmp);
     1691    // if (RT_FAILURE(rc))
     1692    //     return rc;
     1693
     1694    /* Map our ports to IO space. */
     1695    rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0,
     1696                                      VPCI_CONFIG + sizeof(VNetPCIConfig),
     1697                                      PCI_ADDRESS_SPACE_IO, vnetMap);
     1698    if (RT_FAILURE(rc))
     1699        return rc;
     1700
     1701
     1702    /* Register save/restore state handlers. */
     1703    rc = PDMDevHlpSSMRegisterEx(pDevIns, VIRTIO_SAVEDSTATE_VERSION, sizeof(VNETSTATE), NULL,
     1704                                NULL,         vnetLiveExec, NULL,
     1705                                vnetSavePrep, vnetSaveExec, NULL,
     1706                                vnetLoadPrep, vnetLoadExec, vnetLoadDone);
     1707    if (RT_FAILURE(rc))
     1708        return rc;
     1709
     1710    /* Create the RX notifier signaller. */
     1711    rc = PDMDevHlpPDMQueueCreate(pDevIns, sizeof(PDMQUEUEITEMCORE), 1, 0,
     1712                                 vnetCanRxQueueConsumer, true, "VNet-Rcv", &pState->pCanRxQueueR3);
     1713    if (RT_FAILURE(rc))
     1714        return rc;
     1715    pState->pCanRxQueueR0 = PDMQueueR0Ptr(pState->pCanRxQueueR3);
     1716    pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
     1717
     1718    /* Create Link Up Timer */
     1719    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetLinkUpTimer, pState,
     1720                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
     1721                                "VirtioNet Link Up Timer", &pState->pLinkUpTimer);
     1722    if (RT_FAILURE(rc))
     1723        return rc;
     1724
     1725#ifdef VNET_TX_DELAY
     1726    /* Create Transmit Delay Timer */
     1727    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetTxTimer, pState,
     1728                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
     1729                                "VirtioNet TX Delay Timer", &pState->pTxTimerR3);
     1730    if (RT_FAILURE(rc))
     1731        return rc;
     1732    pState->pTxTimerR0 = TMTimerR0Ptr(pState->pTxTimerR3);
     1733    pState->pTxTimerRC = TMTimerRCPtr(pState->pTxTimerR3);
     1734
     1735    pState->u32i = pState->u32AvgDiff = pState->u32MaxDiff = 0;
     1736    pState->u32MinDiff = ~0;
     1737#endif /* VNET_TX_DELAY */
     1738
     1739    rc = PDMDevHlpDriverAttach(pDevIns, 0, &pState->VPCI.IBase, &pState->pDrvBase, "Network Port");
     1740    if (RT_SUCCESS(rc))
     1741    {
     1742        if (rc == VINF_NAT_DNS)
     1743        {
     1744            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
     1745                                       N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
     1746        }
     1747        pState->pDrv = PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMINETWORKCONNECTOR);
     1748        AssertMsgReturn(pState->pDrv, ("Failed to obtain the PDMINETWORKCONNECTOR interface!\n"),
     1749                        VERR_PDM_MISSING_INTERFACE_BELOW);
     1750    }
     1751    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
     1752    {
     1753        Log(("%s This adapter is not attached to any network!\n", INSTANCE(pState)));
     1754    }
     1755    else
     1756        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to attach the network LUN"));
     1757
     1758    rc = RTSemEventCreate(&pState->hEventMoreRxDescAvail);
     1759    if (RT_FAILURE(rc))
     1760        return rc;
     1761
     1762    vnetReset(pState);
     1763
     1764    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveBytes,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,          "Amount of data received",            "/Devices/VNet%d/ReceiveBytes", iInstance);
     1765    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitBytes,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,          "Amount of data transmitted",         "/Devices/VNet%d/TransmitBytes", iInstance);
     1766#if defined(VBOX_WITH_STATISTICS)
     1767    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceive,            STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive",                  "/Devices/VNet%d/Receive/Total", iInstance);
     1768    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveStore,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive storing",          "/Devices/VNet%d/Receive/Store", iInstance);
     1769    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatRxOverflow,         STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, "Profiling RX overflows",        "/Devices/VNet%d/RxOverflow", iInstance);
     1770    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatRxOverflowWakeup,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of RX overflow wakeups",          "/Devices/VNet%d/RxOverflowWakeup", iInstance);
     1771    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmit,           STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling transmits in HC",          "/Devices/VNet%d/Transmit/Total", iInstance);
     1772    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitSend,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling send transmit in HC",      "/Devices/VNet%d/Transmit/Send", iInstance);
     1773#endif /* VBOX_WITH_STATISTICS */
     1774
     1775    return VINF_SUCCESS;
    17721776}
    17731777
  • trunk/src/VBox/Devices/Network/DrvIntNet.cpp

    r25993 r26001  
    711711    LogFlow(("drvR3IntNetDestruct\n"));
    712712    PDRVINTNET pThis = PDMINS_2_DATA(pDrvIns, PDRVINTNET);
     713    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    713714
    714715    /*
     
    778779    PDRVINTNET pThis = PDMINS_2_DATA(pDrvIns, PDRVINTNET);
    779780    bool f;
     781    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    780782
    781783    /*
  • trunk/src/VBox/Devices/Network/DrvNAT.cpp

    r25985 r26001  
    947947{
    948948    PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
    949 
    950949    LogFlow(("drvNATDestruct:\n"));
     950    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    951951
    952952    slirp_term(pThis->pNATState);
     
    969969{
    970970    PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
    971 
    972971    LogFlow(("drvNATConstruct:\n"));
     972    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    973973
    974974    /*
  • trunk/src/VBox/Devices/Network/DrvNetSniffer.cpp

    r25985 r26001  
    332332{
    333333    PDRVNETSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSNIFFER);
     334    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    334335
    335336    if (RTCritSectIsInitialized(&pThis->Lock))
     
    353354    PDRVNETSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSNIFFER);
    354355    LogFlow(("drvNetSnifferConstruct:\n"));
     356    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    355357
    356358    /*
  • trunk/src/VBox/Devices/Network/DrvTAP.cpp

    r25985 r26001  
    775775#endif  /* RT_OS_SOLARIS */
    776776
     777/* -=-=-=-=- PDMIBASE -=-=-=-=- */
    777778
    778779/**
     
    789790}
    790791
     792/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
    791793
    792794/**
     
    802804    LogFlow(("drvTAPDestruct\n"));
    803805    PDRVTAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);
     806    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    804807
    805808    /*
     
    879882{
    880883    PDRVTAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);
     884    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    881885
    882886    /*
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette