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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user