XHCI: Get rid of the PortSlots array and use ControllerCookie in FreeDevice.

This array was introduced by korli in hrev44089~1 (2012). It "mapped"
ports to slots using a device's HubPort, and then used this value in
FreeDevice() to locate the xhci_device struct in question.

Well, when there are non-root hubs in use, the HubPort values can
of course collide, leading us to tear down the wrong device in many
circumstances. This appears to have been the true cause of #16794,
and probably also #16878 and #17266, and maybe even some others.
This commit is contained in:
Augustin Cavalier
2021-09-17 13:33:02 -04:00
parent 31caaec069
commit b3683d8aee
2 changed files with 10 additions and 15 deletions
+10 -14
View File
@@ -402,7 +402,6 @@ XHCI::XHCI(pci_info *info, Stack *stack)
install_io_interrupt_handler(fIRQ, InterruptHandler, (void *)this, 0);
memset(fPortSpeeds, 0, sizeof(fPortSpeeds));
memset(fPortSlots, 0, sizeof(fPortSlots));
memset(fDevices, 0, sizeof(fDevices));
fInitOK = true;
@@ -1656,31 +1655,28 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,
// otherwise happen when this Pipe object is destroyed.
pipe.SetControllerCookie(NULL);
fPortSlots[hubPort] = slot;
TRACE("AllocateDevice() port %d slot %d\n", hubPort, slot);
return deviceObject;
}
void
XHCI::FreeDevice(Device *device)
XHCI::FreeDevice(Device *usbDevice)
{
uint8 hubPort = device->HubPort();
uint8 slot = fPortSlots[hubPort];
TRACE("FreeDevice() port %d slot %d\n", hubPort, slot);
xhci_device* device = (xhci_device*)usbDevice->ControllerCookie();
TRACE("FreeDevice() slot %d\n", device->slot);
// Delete the device first, so it cleans up its pipes and tells us
// what we need to destroy before we tear down our internal state.
delete device;
delete usbDevice;
DisableSlot(slot);
fDcba->baseAddress[slot] = 0;
fPortSlots[hubPort] = 0;
delete_area(fDevices[slot].trb_area);
delete_area(fDevices[slot].input_ctx_area);
delete_area(fDevices[slot].device_ctx_area);
DisableSlot(device->slot);
fDcba->baseAddress[device->slot] = 0;
delete_area(device->trb_area);
delete_area(device->input_ctx_area);
delete_area(device->device_ctx_area);
memset(&fDevices[slot], 0, sizeof(xhci_device));
memset(device, 0, sizeof(xhci_device));
}
-1
View File
@@ -257,7 +257,6 @@ private:
uint8 fPortCount;
uint8 fSlotCount;
usb_speed fPortSpeeds[XHCI_MAX_PORTS];
uint8 fPortSlots[XHCI_MAX_PORTS];
// Scratchpad
uint32 fScratchpadCount;