From bb90c2a6033d59f96da233ff8b68fcddd4c7cbf6 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 10 May 2008 21:09:44 +0000 Subject: [PATCH] * Clear the endpoints of an alternate interface that is going away before updating the active pointer as otherwise the endpoints of the new alternate would have been cleared instead of the old one (leaking endpoints). * Only clear and re-initialize the endpoints of the interface we are setting an alterntate. Otherwise we tear down all the device endpoints which would result in a bad situation for composite devices where multiple drivers may use different functions (through different interfaces) of a device side by side. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25432 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/bus_managers/usb/Device.cpp | 30 ++++++++++++------- src/add-ons/kernel/bus_managers/usb/usb_p.h | 4 +-- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/usb/Device.cpp b/src/add-ons/kernel/bus_managers/usb/Device.cpp index 8d8d3177b7..0d0d468ad2 100644 --- a/src/add-ons/kernel/bus_managers/usb/Device.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Device.cpp @@ -370,7 +370,7 @@ Device::SetConfigurationAt(uint8 index) fCurrentConfiguration = &fConfigurations[index]; // Initialize all the endpoints that are now active - InitEndpoints(); + InitEndpoints(-1); // Wait some for the configuration being finished if (!fIsRootHub) @@ -380,13 +380,16 @@ Device::SetConfigurationAt(uint8 index) void -Device::InitEndpoints() +Device::InitEndpoints(int32 interfaceIndex) { int8 hubAddress = 0; if (Parent() && (Parent()->Type() & USB_OBJECT_HUB)) hubAddress = ((Hub *)Parent())->DeviceAddress(); for (size_t j = 0; j < fCurrentConfiguration->interface_count; j++) { + if (interfaceIndex >= 0 && j != (size_t)interfaceIndex) + continue; + usb_interface_info *interfaceInfo = fCurrentConfiguration->interface[j].active; for (size_t i = 0; i < interfaceInfo->endpoint_count; i++) { usb_endpoint_info *endpoint = &interfaceInfo->endpoint[i]; @@ -424,6 +427,7 @@ Device::InitEndpoints() } } + status_t Device::Unconfigure(bool atDeviceLevel) { @@ -450,17 +454,20 @@ Device::Unconfigure(bool atDeviceLevel) if (!fCurrentConfiguration) return B_OK; - ClearEndpoints(); + ClearEndpoints(-1); fCurrentConfiguration = NULL; return B_OK; } void -Device::ClearEndpoints() +Device::ClearEndpoints(int32 interfaceIndex) { for (size_t j = 0; j < fCurrentConfiguration->interface_count; j++) { + if (interfaceIndex >= 0 && j != (size_t)interfaceIndex) + continue; + usb_interface_info *interfaceInfo = fCurrentConfiguration->interface[j].active; for (size_t i = 0; i < interfaceInfo->endpoint_count; i++) { usb_endpoint_info *endpoint = &interfaceInfo->endpoint[i]; @@ -474,12 +481,13 @@ Device::ClearEndpoints() status_t Device::SetAltInterface(const usb_interface_info *interface) { + uint8 interfaceNumber = interface->descr->interface_number; // Tell the device to set the alternate settings status_t result = fDefaultPipe->SendRequest( USB_REQTYPE_INTERFACE_OUT | USB_REQTYPE_STANDARD, // type USB_REQUEST_SET_INTERFACE, // request interface->descr->alternate_setting, // value - interface->descr->interface_number, // index + interfaceNumber, // index 0, // length NULL, // buffer 0, // buffer length @@ -488,15 +496,17 @@ Device::SetAltInterface(const usb_interface_info *interface) if (result < B_OK) return result; - // Update descriptor + // Clear the no longer active endpoints + ClearEndpoints(interfaceNumber); + + // Update the active pointer of the interface list usb_interface_list *interfaceList - = &fCurrentConfiguration->interface[interface->descr->interface_number]; + = &fCurrentConfiguration->interface[interfaceNumber]; interfaceList->active = &interfaceList->alt[interface->descr->alternate_setting]; - ClearEndpoints(); - InitEndpoints(); - + // Initialize the new endpoints + InitEndpoints(interfaceNumber); return result; } diff --git a/src/add-ons/kernel/bus_managers/usb/usb_p.h b/src/add-ons/kernel/bus_managers/usb/usb_p.h index b138293637..2b222318aa 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb_p.h +++ b/src/add-ons/kernel/bus_managers/usb/usb_p.h @@ -443,8 +443,8 @@ virtual status_t GetDescriptor(uint8 descriptorType, status_t SetAltInterface(const usb_interface_info *interface); - void InitEndpoints(); - void ClearEndpoints(); + void InitEndpoints(int32 interfaceIndex); + void ClearEndpoints(int32 interfaceIndex); virtual status_t ReportDevice( usb_support_descriptor *supportDescriptors,