* Clear the configurations list so it can safely be handled in case the device

fails to init completely.
* Fix wrong usage of realloc and check the allocations.
* Check a few more allocations, should be all now.
* Fix a small memory leaks in error case.
* Do a few more checks when unconfiguring and deleting a device so an incompletely
  initilized device is deleted correctly and does not crash or leak.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25654 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2008-05-25 15:11:34 +00:00
parent d53ddcce75
commit c2f077d03e
+69 -8
View File
@@ -73,6 +73,8 @@ Device::Device(Object *parent, int8 hubPort, usb_device_descriptor &desc,
return; return;
} }
memset(fConfigurations, 0, fDeviceDescriptor.num_configurations
* sizeof(usb_configuration_info));
for (int32 i = 0; i < fDeviceDescriptor.num_configurations; i++) { for (int32 i = 0; i < fDeviceDescriptor.num_configurations; i++) {
usb_configuration_descriptor configDescriptor; usb_configuration_descriptor configDescriptor;
status = GetDescriptor(USB_DESCRIPTOR_CONFIGURATION, i, 0, status = GetDescriptor(USB_DESCRIPTOR_CONFIGURATION, i, 0,
@@ -96,12 +98,20 @@ Device::Device(Object *parent, int8 hubPort, usb_device_descriptor &desc,
TRACE(("\tmax_power:...........%d\n", configDescriptor.max_power)); TRACE(("\tmax_power:...........%d\n", configDescriptor.max_power));
uint8 *configData = (uint8 *)malloc(configDescriptor.total_length); uint8 *configData = (uint8 *)malloc(configDescriptor.total_length);
if (configData == NULL) {
TRACE_ERROR(("USB Device %d: out of memory when reading config\n",
fDeviceAddress));
return;
}
status = GetDescriptor(USB_DESCRIPTOR_CONFIGURATION, i, 0, status = GetDescriptor(USB_DESCRIPTOR_CONFIGURATION, i, 0,
(void *)configData, configDescriptor.total_length, &actualLength); (void *)configData, configDescriptor.total_length, &actualLength);
if (status < B_OK || actualLength != configDescriptor.total_length) { if (status < B_OK || actualLength != configDescriptor.total_length) {
TRACE_ERROR(("USB Device %d: error fetching full configuration" TRACE_ERROR(("USB Device %d: error fetching full configuration"
" descriptor %ld\n", fDeviceAddress, i)); " descriptor %ld got %lu expected %u\n", fDeviceAddress, i,
actualLength, configDescriptor.total_length));
free(configData);
return; return;
} }
@@ -111,6 +121,12 @@ Device::Device(Object *parent, int8 hubPort, usb_device_descriptor &desc,
fConfigurations[i].interface_count = configuration->number_interfaces; fConfigurations[i].interface_count = configuration->number_interfaces;
fConfigurations[i].interface = (usb_interface_list *)malloc( fConfigurations[i].interface = (usb_interface_list *)malloc(
configuration->number_interfaces * sizeof(usb_interface_list)); configuration->number_interfaces * sizeof(usb_interface_list));
if (fConfigurations[i].interface == NULL) {
TRACE_ERROR(("USB Device %d: out of memory when creating interfaces\n",
fDeviceAddress));
return;
}
memset(fConfigurations[i].interface, 0, memset(fConfigurations[i].interface, 0,
configuration->number_interfaces * sizeof(usb_interface_list)); configuration->number_interfaces * sizeof(usb_interface_list));
@@ -137,9 +153,17 @@ Device::Device(Object *parent, int8 hubPort, usb_device_descriptor &desc,
/* Allocate this alternate */ /* Allocate this alternate */
interfaceList->alt_count++; interfaceList->alt_count++;
interfaceList->alt = (usb_interface_info *)realloc( usb_interface_info *newAlternates
interfaceList->alt, interfaceList->alt_count = (usb_interface_info *)realloc(interfaceList->alt,
* sizeof(usb_interface_info)); interfaceList->alt_count * sizeof(usb_interface_info));
if (newAlternates == NULL) {
TRACE_ERROR(("USB Device %d: out of memory allocating"
" alternate interface\n", fDeviceAddress));
interfaceList->alt_count--;
return;
}
interfaceList->alt = newAlternates;
/* Set active interface always to the first one */ /* Set active interface always to the first one */
interfaceList->active = interfaceList->alt; interfaceList->active = interfaceList->alt;
@@ -155,8 +179,13 @@ Device::Device(Object *parent, int8 hubPort, usb_device_descriptor &desc,
Interface *interface = new(std::nothrow) Interface(this, Interface *interface = new(std::nothrow) Interface(this,
interfaceDescriptor->interface_number); interfaceDescriptor->interface_number);
interfaceInfo->handle = interface->USBID(); if (interface == NULL) {
TRACE_ERROR(("USB Device %d: failed to allocate"
" interface object\n", fDeviceAddress));
return;
}
interfaceInfo->handle = interface->USBID();
currentInterface = interfaceInfo; currentInterface = interfaceInfo;
break; break;
} }
@@ -177,10 +206,19 @@ Device::Device(Object *parent, int8 hubPort, usb_device_descriptor &desc,
/* allocate this endpoint */ /* allocate this endpoint */
currentInterface->endpoint_count++; currentInterface->endpoint_count++;
currentInterface->endpoint = (usb_endpoint_info *)realloc( usb_endpoint_info *newEndpoints
= (usb_endpoint_info *)realloc(
currentInterface->endpoint, currentInterface->endpoint,
currentInterface->endpoint_count currentInterface->endpoint_count
* sizeof(usb_endpoint_info)); * sizeof(usb_endpoint_info));
if (newEndpoints == NULL) {
TRACE_ERROR(("USB Device %d: out of memory allocating"
" new endpoint\n", fDeviceAddress));
currentInterface->endpoint_count--;
return;
}
currentInterface->endpoint = newEndpoints;
/* setup this endpoint */ /* setup this endpoint */
usb_endpoint_info *endpointInfo = usb_endpoint_info *endpointInfo =
@@ -202,10 +240,18 @@ Device::Device(Object *parent, int8 hubPort, usb_device_descriptor &desc,
/* allocate this descriptor */ /* allocate this descriptor */
currentInterface->generic_count++; currentInterface->generic_count++;
currentInterface->generic = (usb_descriptor **)realloc( usb_descriptor **newGenerics = (usb_descriptor **)realloc(
currentInterface->generic, currentInterface->generic,
currentInterface->generic_count currentInterface->generic_count
* sizeof(usb_descriptor *)); * sizeof(usb_descriptor *));
if (newGenerics == NULL) {
TRACE_ERROR(("USB Device %d: out of memory allocating"
" generic descriptor\n", fDeviceAddress));
currentInterface->generic_count--;
return;
}
currentInterface->generic = newGenerics;
/* add this descriptor */ /* add this descriptor */
currentInterface->generic[currentInterface->generic_count - 1] = currentInterface->generic[currentInterface->generic_count - 1] =
@@ -239,8 +285,18 @@ Device::~Device()
// Free all allocated resources // Free all allocated resources
for (int32 i = 0; i < fDeviceDescriptor.num_configurations; i++) { for (int32 i = 0; i < fDeviceDescriptor.num_configurations; i++) {
usb_configuration_info *configuration = &fConfigurations[i]; usb_configuration_info *configuration = &fConfigurations[i];
if (configuration == NULL)
continue;
free(configuration->descr);
if (configuration->interface == NULL)
continue;
for (size_t j = 0; j < configuration->interface_count; j++) { for (size_t j = 0; j < configuration->interface_count; j++) {
usb_interface_list *interfaceList = &configuration->interface[j]; usb_interface_list *interfaceList = &configuration->interface[j];
if (interfaceList->alt == NULL)
continue;
for (size_t k = 0; k < interfaceList->alt_count; k++) { for (size_t k = 0; k < interfaceList->alt_count; k++) {
usb_interface_info *interface = &interfaceList->alt[k]; usb_interface_info *interface = &interfaceList->alt[k];
delete (Interface *)GetStack()->GetObject(interface->handle); delete (Interface *)GetStack()->GetObject(interface->handle);
@@ -252,7 +308,6 @@ Device::~Device()
} }
free(configuration->interface); free(configuration->interface);
free(configuration->descr);
} }
free(fConfigurations); free(fConfigurations);
@@ -463,11 +518,17 @@ Device::Unconfigure(bool atDeviceLevel)
void void
Device::ClearEndpoints(int32 interfaceIndex) Device::ClearEndpoints(int32 interfaceIndex)
{ {
if (fCurrentConfiguration == NULL || fCurrentConfiguration->interface == NULL)
return;
for (size_t j = 0; j < fCurrentConfiguration->interface_count; j++) { for (size_t j = 0; j < fCurrentConfiguration->interface_count; j++) {
if (interfaceIndex >= 0 && j != (size_t)interfaceIndex) if (interfaceIndex >= 0 && j != (size_t)interfaceIndex)
continue; continue;
usb_interface_info *interfaceInfo = fCurrentConfiguration->interface[j].active; usb_interface_info *interfaceInfo = fCurrentConfiguration->interface[j].active;
if (interfaceInfo == NULL || interfaceInfo->endpoint == NULL)
continue;
for (size_t i = 0; i < interfaceInfo->endpoint_count; i++) { for (size_t i = 0; i < interfaceInfo->endpoint_count; i++) {
usb_endpoint_info *endpoint = &interfaceInfo->endpoint[i]; usb_endpoint_info *endpoint = &interfaceInfo->endpoint[i];
delete (Pipe *)GetStack()->GetObject(endpoint->handle); delete (Pipe *)GetStack()->GetObject(endpoint->handle);