USB: Rework Device deinitialization and destruction.

* Destroy interfaces and endpoints before deleting the default pipe,
   as all of these may actually use the default pipe at any time
   while they are alive.

 * Remove the default pipe and then ourselves from the stack before
   deleting the default pipe, as it also may be used at any time.

May help with some of the open tickets about USB stack KDLs.
This commit is contained in:
Augustin Cavalier
2021-09-16 13:17:34 -04:00
parent 1fb138bf94
commit 838251124c
2 changed files with 32 additions and 7 deletions
+29 -7
View File
@@ -329,6 +329,34 @@ Device::~Device()
// Unset fInitOK to indicate we are tearing down.
fInitOK = false;
// Destroy open endpoints. Do not send a device request to unconfigure
// though, since we may be deleted because the device was unplugged already.
Unconfigure(false);
// Destroy all Interfaces in the Configurations hierarchy.
for (int32 i = 0; fConfigurations != NULL
&& i < fDeviceDescriptor.num_configurations; i++) {
usb_configuration_info* configuration = &fConfigurations[i];
if (configuration == NULL || configuration->interface == NULL)
continue;
for (size_t j = 0; j < configuration->interface_count; j++) {
usb_interface_list* interfaceList = &configuration->interface[j];
if (interfaceList->alt == NULL)
continue;
for (size_t k = 0; k < interfaceList->alt_count; k++) {
usb_interface_info* interface = &interfaceList->alt[k];
delete (Interface*)GetStack()->GetObject(interface->handle);
interface->handle = 0;
}
}
}
// Remove ourselves from the stack before deleting public structures.
if (fDefaultPipe != NULL)
fDefaultPipe->PutUSBID();
PutUSBID();
delete fDefaultPipe;
if (fConfigurations == NULL) {
@@ -336,12 +364,7 @@ Device::~Device()
return;
}
// Destroy open endpoints. Do not send a device request to unconfigure
// though, since we may be deleted because the device was unplugged
// already.
Unconfigure(false);
// Free all allocated resources
// Free the Configurations hierarchy.
for (int32 i = 0; i < fDeviceDescriptor.num_configurations; i++) {
usb_configuration_info* configuration = &fConfigurations[i];
if (configuration == NULL)
@@ -358,7 +381,6 @@ Device::~Device()
for (size_t k = 0; k < interfaceList->alt_count; k++) {
usb_interface_info* interface = &interfaceList->alt[k];
delete (Interface*)GetStack()->GetObject(interface->handle);
free(interface->endpoint);
free(interface->generic);
}
@@ -347,6 +347,9 @@ virtual status_t SetFeature(uint16 selector);
virtual status_t ClearFeature(uint16 selector);
virtual status_t GetStatus(uint16 *status);
protected:
friend class Device;
private:
int8 fDeviceAddress;
uint8 fEndpointAddress;