Changeset 93939 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Feb 24, 2022 5:23:37 PM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 150168
- Location:
- trunk/src/VBox/Devices/USB
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
r93934 r93939 258 258 pDev = pThis->apDevByPort[uPort]; 259 259 if (RT_LIKELY(pDev)) 260 ASMAtomicIncU32(&pDev->cRefs); 260 vusbDevRetain(pDev); 261 262 RTCritSectLeave(&pThis->CritSectDevices); 263 264 return pDev; 265 } 266 267 268 /** 269 * Returns the attached VUSB device for the given port or NULL if none is attached. 270 * 271 * @returns Pointer to the VUSB device or NULL if not found. 272 * @param pThis The VUSB roothub device instance. 273 * @param u8Address The address to get the device for. 274 * 275 * @note The reference count of the VUSB device structure is retained to prevent it from going away. 276 */ 277 static PVUSBDEV vusbR3RhGetVUsbDevByAddrRetain(PVUSBROOTHUB pThis, uint8_t u8Address) 278 { 279 PVUSBDEV pDev = NULL; 280 281 AssertReturn(u8Address < RT_ELEMENTS(pThis->apDevByAddr), NULL); 282 283 RTCritSectEnter(&pThis->CritSectDevices); 284 285 pDev = pThis->apDevByAddr[u8Address]; 286 if (RT_LIKELY(pDev)) 287 vusbDevRetain(pDev); 261 288 262 289 RTCritSectLeave(&pThis->CritSectDevices); … … 353 380 354 381 /** 355 * Finds an device attached to a roothub by it's address.356 *357 * @returns Pointer to the device.358 * @returns NULL if not found.359 * @param pRh Pointer to the root hub.360 * @param Address The device address.361 */362 static PVUSBDEV vusbRhFindDevByAddress(PVUSBROOTHUB pRh, uint8_t Address)363 {364 unsigned iHash = vusbHashAddress(Address);365 PVUSBDEV pDev = NULL;366 367 RTCritSectEnter(&pRh->CritSectDevices);368 for (PVUSBDEV pCur = pRh->apAddrHash[iHash]; pCur; pCur = pCur->pNextHash)369 if (pCur->u8Address == Address)370 {371 pDev = pCur;372 break;373 }374 375 if (pDev)376 vusbDevRetain(pDev);377 RTCritSectLeave(&pRh->CritSectDevices);378 return pDev;379 }380 381 382 /**383 382 * Callback for freeing an URB. 384 383 * @param pUrb The URB to free. … … 434 433 PVUSBDEV pDev; 435 434 if (uPort == VUSB_DEVICE_PORT_INVALID) 436 pDev = vusbR hFindDevByAddress(pRh, DstAddress);435 pDev = vusbR3RhGetVUsbDevByAddrRetain(pRh, DstAddress); 437 436 else 438 437 pDev = vusbR3RhGetVUsbDevByPortRetain(pRh, uPort); … … 1449 1448 Assert(pDev->i16Port != -1); 1450 1449 1451 /* 1452 * Check that it's attached and unlink it from the linked list. 1453 */ 1450 /* Check that it's attached and remvoe it. */ 1454 1451 RTCritSectEnter(&pRh->CritSectDevices); 1455 1452 Assert(pRh->apDevByPort[pDev->i16Port] == pDev); 1456 pRh->apDevByPort[pDev->i16Port] = NULL; 1453 pRh->apDevByPort[pDev->i16Port] = NULL; 1454 1455 if (pDev->u8Address == VUSB_DEFAULT_ADDRESS) 1456 { 1457 AssertPtr(pRh->apDevByAddr[VUSB_DEFAULT_ADDRESS]); 1458 1459 if (pDev == pRh->apDevByAddr[VUSB_DEFAULT_ADDRESS]) 1460 pRh->apDevByAddr[VUSB_DEFAULT_ADDRESS] = pDev->pNextDefAddr; 1461 else 1462 { 1463 /* Search the list for the device and remove it. */ 1464 PVUSBDEV pDevPrev = pRh->apDevByAddr[VUSB_DEFAULT_ADDRESS]; 1465 1466 while ( pDevPrev 1467 && pDevPrev->pNextDefAddr != pDev) 1468 pDevPrev = pDevPrev->pNextDefAddr; 1469 1470 AssertPtr(pDevPrev); 1471 pDevPrev->pNextDefAddr = pDev->pNextDefAddr; 1472 } 1473 1474 pDev->pNextDefAddr = NULL; 1475 } 1476 else 1477 { 1478 Assert(pRh->apDevByAddr[pDev->u8Address] == pDev); 1479 pRh->apDevByAddr[pDev->u8Address] = NULL; 1480 } 1457 1481 RTCritSectLeave(&pRh->CritSectDevices); 1458 1482 -
trunk/src/VBox/Devices/USB/VUSBDevice.cpp
r93914 r93939 994 994 995 995 /** 996 * Add a device to the address hash997 */998 static void vusbDevAddressHash(PVUSBDEV pDev)999 {1000 if (pDev->u8Address == VUSB_INVALID_ADDRESS)1001 return;1002 uint8_t u8Hash = vusbHashAddress(pDev->u8Address);1003 pDev->pNextHash = pDev->pHub->pRootHub->apAddrHash[u8Hash];1004 pDev->pHub->pRootHub->apAddrHash[u8Hash] = pDev;1005 }1006 1007 /**1008 * Remove a device from the address hash1009 */1010 static void vusbDevAddressUnHash(PVUSBDEV pDev)1011 {1012 if (pDev->u8Address == VUSB_INVALID_ADDRESS)1013 return;1014 1015 uint8_t u8Hash = vusbHashAddress(pDev->u8Address);1016 pDev->u8Address = VUSB_INVALID_ADDRESS;1017 pDev->u8NewAddress = VUSB_INVALID_ADDRESS;1018 1019 RTCritSectEnter(&pDev->pHub->pRootHub->CritSectDevices);1020 PVUSBDEV pCur = pDev->pHub->pRootHub->apAddrHash[u8Hash];1021 if (pCur == pDev)1022 {1023 /* special case, we're at the head */1024 pDev->pHub->pRootHub->apAddrHash[u8Hash] = pDev->pNextHash;1025 pDev->pNextHash = NULL;1026 }1027 else1028 {1029 /* search the list */1030 PVUSBDEV pPrev;1031 for (pPrev = pCur, pCur = pCur->pNextHash;1032 pCur;1033 pPrev = pCur, pCur = pCur->pNextHash)1034 {1035 if (pCur == pDev)1036 {1037 pPrev->pNextHash = pCur->pNextHash;1038 pDev->pNextHash = NULL;1039 break;1040 }1041 }1042 }1043 RTCritSectLeave(&pDev->pHub->pRootHub->CritSectDevices);1044 }1045 1046 /**1047 996 * Sets the address of a device. 1048 997 * … … 1077 1026 return; 1078 1027 1028 /** @todo The following logic belongs to the roothub and should actually be in that file. */ 1079 1029 PVUSBROOTHUB pRh = vusbDevGetRh(pDev); 1080 1030 AssertPtrReturnVoid(pRh); 1031 1032 RTCritSectEnter(&pRh->CritSectDevices); 1033 1034 /* Remove the device from the current address. */ 1081 1035 if (pDev->u8Address == VUSB_DEFAULT_ADDRESS) 1082 pRh->pDefaultAddress = NULL; 1083 1084 vusbDevAddressUnHash(pDev); 1036 { 1037 AssertPtr(pRh->apDevByAddr[VUSB_DEFAULT_ADDRESS]); 1038 1039 if (pDev == pRh->apDevByAddr[VUSB_DEFAULT_ADDRESS]) 1040 pRh->apDevByAddr[VUSB_DEFAULT_ADDRESS] = pDev->pNextDefAddr; 1041 else 1042 { 1043 /* Search the list for the device and remove it. */ 1044 PVUSBDEV pDevPrev = pRh->apDevByAddr[VUSB_DEFAULT_ADDRESS]; 1045 1046 while ( pDevPrev 1047 && pDevPrev->pNextDefAddr != pDev) 1048 pDevPrev = pDevPrev->pNextDefAddr; 1049 1050 AssertPtr(pDevPrev); 1051 pDevPrev->pNextDefAddr = pDev->pNextDefAddr; 1052 } 1053 1054 pDev->pNextDefAddr = NULL; 1055 } 1056 else 1057 pRh->apDevByAddr[pDev->u8Address] = NULL; 1085 1058 1086 1059 if (u8Address == VUSB_DEFAULT_ADDRESS) 1087 1060 { 1088 if (pRh->pDefaultAddress != NULL) 1061 PVUSBDEV pDevDef = pRh->apDevByAddr[VUSB_DEFAULT_ADDRESS]; 1062 1063 if (pDevDef) 1089 1064 { 1090 vusbDevAddressUnHash(pRh->pDefaultAddress); 1091 vusbDevSetStateCmp(pRh->pDefaultAddress, VUSB_DEVICE_STATE_POWERED, VUSB_DEVICE_STATE_DEFAULT); 1065 vusbDevSetStateCmp(pDevDef, VUSB_DEVICE_STATE_POWERED, VUSB_DEVICE_STATE_DEFAULT); 1092 1066 Log(("2 DEFAULT ADDRS\n")); 1093 1067 } 1094 1068 1095 pRh->pDefaultAddress = pDev; 1069 pDev->pNextDefAddr = pDevDef; 1070 pRh->apDevByAddr[VUSB_DEFAULT_ADDRESS] = pDev; 1096 1071 vusbDevSetState(pDev, VUSB_DEVICE_STATE_DEFAULT); 1097 1072 } 1098 1073 else 1074 { 1075 Assert(!pRh->apDevByAddr[u8Address]); 1076 pRh->apDevByAddr[u8Address] = pDev; 1099 1077 vusbDevSetState(pDev, VUSB_DEVICE_STATE_ADDRESS); 1078 } 1079 1080 RTCritSectLeave(&pRh->CritSectDevices); 1100 1081 1101 1082 pDev->u8Address = u8Address; 1102 vusbDevAddressHash(pDev);1103 1083 1104 1084 Log(("vusb: %p[%s]/%i: Assigned address %u\n", … … 1327 1307 1328 1308 vusbDevCancelAllUrbs(pDev, true); 1329 vusbDevAddressUnHash(pDev);1330 1309 1331 1310 PVUSBROOTHUB pRh = vusbDevGetRh(pDev); 1332 1311 if (!pRh) 1333 1312 AssertMsgFailedReturn(("Not attached!\n"), VERR_VUSB_DEVICE_NOT_ATTACHED); 1334 if (pRh->pDefaultAddress == pDev) 1335 pRh->pDefaultAddress = NULL; 1336 1313 1314 /* The roothub will remove the device from the address to device array. */ 1337 1315 pDev->pHub->pOps->pfnDetach(pDev->pHub, pDev); 1338 1316 pDev->i16Port = -1; … … 1842 1820 pDev->IDevice.pfnGetSpeed = vusbIDeviceGetSpeed; 1843 1821 pDev->pUsbIns = pUsbIns; 1844 pDev->pNext = NULL; 1845 pDev->pNextHash = NULL; 1822 pDev->pNextDefAddr = NULL; 1846 1823 pDev->pHub = NULL; 1847 1824 pDev->enmState = VUSB_DEVICE_STATE_DETACHED; -
trunk/src/VBox/Devices/USB/VUSBInternal.h
r93934 r93939 225 225 /** Pointer to the PDM USB device instance. */ 226 226 PPDMUSBINS pUsbIns; 227 /** Next device in the chain maintained by the roothub. */ 228 PVUSBDEV pNext; 229 /** Pointer to the next device with the same address hash. */ 230 PVUSBDEV pNextHash; 227 /** Next device in the chain of devices with the default address. */ 228 PVUSBDEV pNextDefAddr; 231 229 /** Pointer to the hub this device is attached to. */ 232 230 PVUSBHUB pHub; … … 380 378 typedef struct VUSBROOTHUBLOAD *PVUSBROOTHUBLOAD; 381 379 382 /** The address hash table size. */383 #define VUSB_ADDR_HASHSZ 5384 385 380 /** 386 381 * The instance data of a root hub driver. … … 395 390 * @todo remove this? */ 396 391 VUSBHUB Hub; 397 /** Address hash table. */398 PVUSBDEV apAddrHash[VUSB_ADDR_HASHSZ];399 /** The default address. */400 PVUSBDEV pDefaultAddress;401 402 392 /** Pointer to the driver instance. */ 403 393 PPDMDRVINS pDrvIns; … … 411 401 /** Array of pointers to USB devices indexed by the port the device is on. */ 412 402 PVUSBDEV apDevByPort[VUSB_DEVICES_MAX]; 403 /** Array of pointers to USB devices indexed by the address assigned. */ 404 PVUSBDEV apDevByAddr[VUSB_DEVICES_MAX]; 413 405 /** Structure after a saved state load to re-attach devices. */ 414 406 PVUSBROOTHUBLOAD pLoad; … … 644 636 645 637 646 647 648 /**649 * Addresses are between 0 and 127 inclusive650 */651 DECLINLINE(uint8_t) vusbHashAddress(uint8_t Address)652 {653 uint8_t u8Hash = Address;654 u8Hash ^= (Address >> 2);655 u8Hash ^= (Address >> 3);656 u8Hash %= VUSB_ADDR_HASHSZ;657 return u8Hash;658 }659 660 661 638 /** 662 639 * Gets the roothub of a device.
Note:
See TracChangeset
for help on using the changeset viewer.