Changeset 26001 in vbox for trunk/src/VBox/Devices/Network/DevE1000.cpp
- Timestamp:
- Jan 25, 2010 2:21:13 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 56881
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevE1000.cpp
r25986 r26001 4724 4724 } 4725 4725 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 */ 4739 static 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 */ 4774 static 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 */ 4831 static DECLCALLBACK(void) e1kPowerOff(PPDMDEVINS pDevIns) 4832 { 4833 /* Poke thread waiting for buffer space. */ 4834 e1kWakeupReceive(pDevIns); 4835 } 4836 4837 /** 4838 * @copydoc FNPDMDEVSUSPEND 4839 */ 4840 static 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 */ 4862 static 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 */ 4890 static 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 4726 4919 /** 4727 4920 * Sets 8-bit register in PCI configuration space. … … 4847 5040 E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*); 4848 5041 int rc; 5042 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); 4849 5043 4850 5044 /* Init handles and log related stuff. */ … … 5129 5323 5130 5324 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 EMT5141 */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_MUTEX5162 PDMR3CritSectDelete(&pState->csRx);5163 //PDMR3CritSectDelete(&pState->csTx);5164 #endif5165 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 the5174 * device have a GC component, is being relocated, or/and the selectors5175 * have been changed. The device must use the chance to perform the5176 * necessary pointer relocations and data updates.5177 *5178 * Before the GC code is executed the first time, this function will be5179 * 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_TIMERS5193 pState->pRIDTimerRC = TMTimerRCPtr(pState->pRIDTimerR3);5194 pState->pRADTimerRC = TMTimerRCPtr(pState->pRADTimerR3);5195 #endif /* E1K_USE_RX_TIMERS */5196 #ifdef E1K_USE_TX_TIMERS5197 pState->pTIDTimerRC = TMTimerRCPtr(pState->pTIDTimerR3);5198 # ifndef E1K_NO_TAD5199 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 FNPDMDEVSUSPEND5207 */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_ATTACH5216 /**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 missed5235 * to clean something in this function5236 */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_LINUX5278 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 #else5281 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 #endif5284 }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 guest5295 * will know that we have change the configuration of the5296 * network card5297 */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 FNPDMDEVPOWEROFF5316 */5317 static DECLCALLBACK(void) e1kPowerOff(PPDMDEVINS pDevIns)5318 {5319 /* Poke thread waiting for buffer space. */5320 e1kWakeupReceive(pDevIns);5321 5325 } 5322 5326
Note:
See TracChangeset
for help on using the changeset viewer.