* 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
This commit is contained in:
parent
899aa8e1f6
commit
bb90c2a603
src/add-ons/kernel/bus_managers/usb
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user