- Timestamp:
- Dec 13, 2024 8:13:55 AM (3 months ago)
- svn:sync-xref-src-repo-rev:
- 166340
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/VBox/Devices/Network/UsbNet.cpp ¶
r107243 r107309 377 377 /** If set the link is temporarily down because of a saved state load. */ 378 378 bool fLinkTempDown; 379 /** Link Up(/Restore) Timer. */ 380 TMTIMERHANDLE hTimerLinkUp; 379 381 380 382 bool fInitialLinkStatusSent; … … 1368 1370 1369 1371 1372 DECLHIDDEN(void) usbNetLinkStateNotify(PUSBNET pThis, PDMNETWORKLINKSTATE enmLinkState); 1373 1374 /** 1375 * @callback_method_impl{FNTMTIMERUSB} 1376 * 1377 * By the time the host resumes after sleep the network environment may have changed considerably. 1378 * We handle this by temporarily lowering the link state. This callback brings the link back up. 1379 */ 1380 static DECLCALLBACK(void) usbNetTimerLinkUp(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer, void *pvUser) 1381 { 1382 PUSBNET pThis = (PUSBNET)pvUser; 1383 RT_NOREF(pUsbIns, hTimer); 1384 1385 LogFlowFunc(("#%d\n", pUsbIns->iInstance)); 1386 1387 /* @todo: Do we really care for potential races with link state? */ 1388 pThis->fLinkTempDown = false; 1389 if (!pThis->fLinkUp) 1390 usbNetLinkStateNotify(pThis, PDMNETWORKLINKSTATE_UP); 1391 } 1392 1393 1370 1394 /** 1371 1395 * @interface_method_impl{PDMINETWORKCONFIG,pfnSetLinkState} … … 1375 1399 PUSBNET pThis = RT_FROM_MEMBER(pInterface, USBNET, Lun0.INetworkConfig); 1376 1400 1377 //bool fLinkUp;1378 1379 LogFlowFunc(("#%d \n", pThis->pUsbIns->iInstance));1401 bool fLinkUp = enmState == PDMNETWORKLINKSTATE_UP; 1402 1403 LogFlowFunc(("#%d enmState=%d\n", pThis->pUsbIns->iInstance, enmState)); 1380 1404 AssertMsgReturn(enmState > PDMNETWORKLINKSTATE_INVALID && enmState <= PDMNETWORKLINKSTATE_DOWN_RESUME, 1381 1405 ("Invalid link state: enmState=%d\n", enmState), VERR_INVALID_PARAMETER); 1382 RT_NOREF(pThis); 1383 1384 #if 0 1406 1385 1407 if (enmState == PDMNETWORKLINKSTATE_DOWN_RESUME) 1386 1408 { 1387 dp8390TempLinkDown(pDevIns, pThis); 1388 /* 1389 * Note that we do not notify the driver about the link state change because 1390 * the change is only temporary and can be disregarded from the driver's 1391 * point of view (see @bugref{7057}). 1392 */ 1393 return VINF_SUCCESS; 1409 pThis->fLinkTempDown = true; 1410 /* Do not bother to notify anyone if the link has been down */ 1411 PDMUsbHlpTimerSetMillies(pThis->pUsbIns, pThis->hTimerLinkUp, 500); /* 0.5 sec */ 1394 1412 } 1395 1413 /* has the state changed? */ 1396 fLinkUp = enmState == PDMNETWORKLINKSTATE_UP;1397 1414 if (pThis->fLinkUp != fLinkUp) 1398 1415 { 1399 1416 pThis->fLinkUp = fLinkUp; 1400 if (fLinkUp) 1401 { 1402 /* Connect with a configured delay. */ 1403 pThis->fLinkTempDown = true; 1404 pThis->cLinkDownReported = 0; 1405 pThis->cLinkRestorePostponed = 0; 1406 pThis->Led.Asserted.s.fError = pThis->Led.Actual.s.fError = 1; 1407 int rc = PDMDevHlpTimerSetMillies(pDevIns, pThis->hTimerRestore, pThis->cMsLinkUpDelay); 1408 AssertRC(rc); 1409 } 1410 else 1411 { 1412 /* Disconnect. */ 1413 pThis->cLinkDownReported = 0; 1414 pThis->cLinkRestorePostponed = 0; 1415 pThis->Led.Asserted.s.fError = pThis->Led.Actual.s.fError = 1; 1416 } 1417 Assert(!PDMDevHlpCritSectIsOwner(pDevIns, &pThis->CritSect)); 1418 if (pThisCC->pDrv) 1419 pThisCC->pDrv->pfnNotifyLinkChanged(pThisCC->pDrv, enmState); 1420 } 1421 #endif 1417 usbNetLinkStateNotify(pThis, enmState); 1418 } 1422 1419 return VINF_SUCCESS; 1423 1420 } … … 1665 1662 return usbNetCompleteStall(pThis, NULL, pUrb, pEp->fHalted ? "Halted pipe" : "No request"); 1666 1663 1667 if (!pThis->fInitialLinkStatusSent) 1668 { 1669 USBCDCNOTIFICICATION LinkNotification; 1670 LinkNotification.bmRequestType = 0xa1; 1671 LinkNotification.bNotificationCode = USB_CDC_NOTIFICATION_CODE_NETWORK_CONNECTION; 1672 LinkNotification.wValue = pThis->fLinkUp ? 1 : 0; 1673 LinkNotification.wIndex = 0; 1674 LinkNotification.wLength = 0; 1675 usbNetCompleteNotificationOk(pThis, pUrb, &LinkNotification, sizeof(LinkNotification)); 1676 pThis->fInitialLinkStatusSent = true; 1677 } 1678 else if (!pThis->fInitialSpeedChangeSent) 1664 /* CONNECTION_SPEED_CHANGE is sent first, followed by NETWORK_CONNECTION. See [NCM10] (section 7.1) */ 1665 if (!pThis->fInitialSpeedChangeSent) 1679 1666 { 1680 1667 USBCDCNOTIFICICATIONSPEEDCHG SpeedChange; … … 1689 1676 pThis->fInitialSpeedChangeSent = true; 1690 1677 } 1678 else if (!pThis->fInitialLinkStatusSent) 1679 { 1680 USBCDCNOTIFICICATION LinkNotification; 1681 LinkNotification.bmRequestType = 0xa1; 1682 LinkNotification.bNotificationCode = USB_CDC_NOTIFICATION_CODE_NETWORK_CONNECTION; 1683 LinkNotification.wValue = pThis->fLinkUp ? 1 : 0; 1684 LinkNotification.wIndex = 0; 1685 LinkNotification.wLength = 0; 1686 usbNetCompleteNotificationOk(pThis, pUrb, &LinkNotification, sizeof(LinkNotification)); 1687 pThis->fInitialLinkStatusSent = true; 1688 } 1691 1689 else 1692 1690 usbNetQueueAddTail(&pThis->ToHostIntrQueue, pUrb); … … 1694 1692 LogFlow(("usbNetHandleIntrDevToHost: Added %p:%s to the to-host interrupt queue\n", pUrb, pUrb->pszDesc)); 1695 1693 return VINF_SUCCESS; 1694 } 1695 1696 1697 /** 1698 * Notifies both the guest and the network/driver of link state changes. 1699 * 1700 * @param pThis The UsbNet instance. 1701 * @param enmLinkState The new link state. 1702 */ 1703 DECLHIDDEN(void) usbNetLinkStateNotify(PUSBNET pThis, PDMNETWORKLINKSTATE enmLinkState) 1704 { 1705 LogFlowFunc(("#%d enmLinkState=%d\n", pThis->pUsbIns->iInstance, enmLinkState)); 1706 RTCritSectEnter(&pThis->CritSect); 1707 /* Trigger notifications */ 1708 pThis->fInitialLinkStatusSent = false; 1709 pThis->fInitialSpeedChangeSent = false; 1710 PVUSBURB pUrb = usbNetQueueRemoveHead(&pThis->ToHostIntrQueue); 1711 /* If there is a request pending, use it. Otherwise the host should poll us soon. */ 1712 if (pUrb) 1713 usbNetHandleIntrDevToHost(pThis, &pThis->aEps[3], pUrb); 1714 RTCritSectLeave(&pThis->CritSect); 1715 /* Always notify our network when notifying the guest. */ 1716 if (pThis->Lun0.pINetwork) 1717 pThis->Lun0.pINetwork->pfnNotifyLinkChanged(pThis->Lun0.pINetwork, enmLinkState); 1696 1718 } 1697 1719 … … 2097 2119 LogFlow(("usbNetDestruct/#%u:\n", pUsbIns->iInstance)); 2098 2120 2121 PDMUsbHlpTimerDestroy(pUsbIns, pThis->hTimerLinkUp); 2122 2099 2123 if (RTCritSectIsInitialized(&pThis->CritSect)) 2100 2124 { … … 2204 2228 return PDMUsbHlpVMSetError(pUsbIns, VERR_PDM_MISSING_INTERFACE_BELOW, RT_SRC_POS, 2205 2229 N_("USBNET failed to query the PDMINETWORKUP from the driver below it")); 2230 2231 /* 2232 * Create the timer for delaying of bringing the link up. 2233 */ 2234 rc = PDMUsbHlpTimerCreate(pUsbIns, TMCLOCK_VIRTUAL, usbNetTimerLinkUp, pThis, 2235 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, 2236 "Link Up", &pThis->hTimerLinkUp); 2206 2237 2207 2238 /*
Note:
See TracChangeset
for help on using the changeset viewer.