* Fix off-by-one error in port number which caused full- or lowspeed devices
behind highspeed hubs with multiple transaction translators not to work. * The parent hub isn't necessarily the one providing the transaction translator for a full- or lowspeed device. Therefore we need to inherit the hub/port addresses to lower devices unless we are a highspeed hub that might be the actual provider of the transaction translator. This logic error caused full- and lowspeed devices not to work if they were behind a fullspeed hub that itself was behind a highspeed hub. This fixes bugs #1889 and #2501. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26552 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
e36b6d3e2c
commit
a524312842
@ -112,7 +112,8 @@ BusManager::FreeAddress(int8 address)
|
||||
|
||||
|
||||
Device *
|
||||
BusManager::AllocateDevice(Hub *parent, uint8 port, usb_speed speed)
|
||||
BusManager::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,
|
||||
usb_speed speed)
|
||||
{
|
||||
// Check if there is a free entry in the device map (for the device number)
|
||||
int8 deviceAddress = AllocateAddress();
|
||||
@ -123,7 +124,7 @@ BusManager::AllocateDevice(Hub *parent, uint8 port, usb_speed speed)
|
||||
|
||||
TRACE(("USB BusManager: setting device address to %d\n", deviceAddress));
|
||||
ControlPipe *defaultPipe = _GetDefaultPipe(speed);
|
||||
defaultPipe->SetHubInfo(parent->DeviceAddress(), port);
|
||||
defaultPipe->SetHubInfo(hubAddress, hubPort);
|
||||
|
||||
if (!defaultPipe) {
|
||||
TRACE_ERROR(("USB BusManager: error getting the default pipe for speed %d\n", (int)speed));
|
||||
@ -161,8 +162,8 @@ BusManager::AllocateDevice(Hub *parent, uint8 port, usb_speed speed)
|
||||
|
||||
// Create a temporary pipe with the new address
|
||||
ControlPipe pipe(fRootObject);
|
||||
pipe.InitCommon(deviceAddress, 0, speed, Pipe::Default, 8, 0,
|
||||
parent->DeviceAddress(), port);
|
||||
pipe.InitCommon(deviceAddress, 0, speed, Pipe::Default, 8, 0, hubAddress,
|
||||
hubPort);
|
||||
|
||||
// Get the device descriptor
|
||||
// Just retrieve the first 8 bytes of the descriptor -> minimum supported
|
||||
@ -200,8 +201,8 @@ BusManager::AllocateDevice(Hub *parent, uint8 port, usb_speed speed)
|
||||
// Create a new instance based on the type (Hub or Device)
|
||||
if (deviceDescriptor.device_class == 0x09) {
|
||||
TRACE(("USB BusManager: creating new hub\n"));
|
||||
Hub *hub = new(std::nothrow) Hub(parent, port, deviceDescriptor,
|
||||
deviceAddress, speed, false);
|
||||
Hub *hub = new(std::nothrow) Hub(parent, hubAddress, hubPort,
|
||||
deviceDescriptor, deviceAddress, speed, false);
|
||||
if (!hub) {
|
||||
TRACE_ERROR(("USB BusManager: no memory to allocate hub\n"));
|
||||
FreeAddress(deviceAddress);
|
||||
@ -219,8 +220,8 @@ BusManager::AllocateDevice(Hub *parent, uint8 port, usb_speed speed)
|
||||
}
|
||||
|
||||
TRACE(("USB BusManager: creating new device\n"));
|
||||
Device *device = new(std::nothrow) Device(parent, port, deviceDescriptor,
|
||||
deviceAddress, speed, false);
|
||||
Device *device = new(std::nothrow) Device(parent, hubAddress, hubPort,
|
||||
deviceDescriptor, deviceAddress, speed, false);
|
||||
if (!device) {
|
||||
TRACE_ERROR(("USB BusManager: no memory to allocate device\n"));
|
||||
FreeAddress(deviceAddress);
|
||||
|
@ -10,8 +10,9 @@
|
||||
#include "usb_p.h"
|
||||
|
||||
|
||||
Device::Device(Object *parent, int8 hubPort, usb_device_descriptor &desc,
|
||||
int8 deviceAddress, usb_speed speed, bool isRootHub)
|
||||
Device::Device(Object *parent, int8 hubAddress, uint8 hubPort,
|
||||
usb_device_descriptor &desc, int8 deviceAddress, usb_speed speed,
|
||||
bool isRootHub)
|
||||
: Object(parent),
|
||||
fDeviceDescriptor(desc),
|
||||
fInitOK(false),
|
||||
@ -21,6 +22,7 @@ Device::Device(Object *parent, int8 hubPort, usb_device_descriptor &desc,
|
||||
fCurrentConfiguration(NULL),
|
||||
fSpeed(speed),
|
||||
fDeviceAddress(deviceAddress),
|
||||
fHubAddress(hubAddress),
|
||||
fHubPort(hubPort)
|
||||
{
|
||||
TRACE(("USB Device %d: creating device\n", fDeviceAddress));
|
||||
@ -31,11 +33,8 @@ Device::Device(Object *parent, int8 hubPort, usb_device_descriptor &desc,
|
||||
return;
|
||||
}
|
||||
|
||||
int8 hubAddress = 0;
|
||||
if (parent->Type() & USB_OBJECT_HUB)
|
||||
hubAddress = ((Hub *)parent)->DeviceAddress();
|
||||
fDefaultPipe->InitCommon(fDeviceAddress, 0, fSpeed, Pipe::Default,
|
||||
fDeviceDescriptor.max_packet_size_0, 0, hubAddress, fHubPort);
|
||||
fDeviceDescriptor.max_packet_size_0, 0, fHubAddress, fHubPort);
|
||||
|
||||
// Get the device descriptor
|
||||
// We already have a part of it, but we want it all
|
||||
@ -436,10 +435,6 @@ Device::SetConfigurationAt(uint8 index)
|
||||
void
|
||||
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;
|
||||
@ -475,7 +470,7 @@ Device::InitEndpoints(int32 interfaceIndex)
|
||||
pipe->InitCommon(fDeviceAddress,
|
||||
endpoint->descr->endpoint_address & 0x0f,
|
||||
fSpeed, direction, endpoint->descr->max_packet_size,
|
||||
endpoint->descr->interval, hubAddress, fHubPort);
|
||||
endpoint->descr->interval, fHubAddress, fHubPort);
|
||||
endpoint->handle = pipe->USBID();
|
||||
}
|
||||
}
|
||||
|
@ -11,9 +11,11 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
Hub::Hub(Object *parent, int8 hubPort, usb_device_descriptor &desc,
|
||||
int8 deviceAddress, usb_speed speed, bool isRootHub)
|
||||
: Device(parent, hubPort, desc, deviceAddress, speed, isRootHub),
|
||||
Hub::Hub(Object *parent, int8 hubAddress, uint8 hubPort,
|
||||
usb_device_descriptor &desc, int8 deviceAddress, usb_speed speed,
|
||||
bool isRootHub)
|
||||
: Device(parent, hubAddress, hubPort, desc, deviceAddress, speed,
|
||||
isRootHub),
|
||||
fInterruptPipe(NULL)
|
||||
{
|
||||
TRACE(("USB Hub %d: creating hub\n", DeviceAddress()));
|
||||
@ -61,16 +63,16 @@ Hub::Hub(Object *parent, int8 hubPort, usb_device_descriptor &desc,
|
||||
fHubDescriptor.num_ports = USB_MAX_PORT_COUNT;
|
||||
}
|
||||
|
||||
Object *object = GetStack()->GetObject(Configuration()->interface->active->endpoint[0].handle);
|
||||
if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) {
|
||||
usb_interface_list *list = Configuration()->interface;
|
||||
Object *object = GetStack()->GetObject(list->active->endpoint[0].handle);
|
||||
if (object && (object->Type() & USB_OBJECT_INTERRUPT_PIPE) != 0) {
|
||||
fInterruptPipe = (InterruptPipe *)object;
|
||||
fInterruptPipe->QueueInterrupt(fInterruptStatus,
|
||||
sizeof(fInterruptStatus), InterruptCallback, this);
|
||||
} else {
|
||||
TRACE_ERROR(("USB Hub %d: no interrupt pipe found\n", DeviceAddress()));
|
||||
return;
|
||||
}
|
||||
|
||||
fInterruptPipe = (InterruptPipe *)object;
|
||||
fInterruptPipe->QueueInterrupt(fInterruptStatus, sizeof(fInterruptStatus),
|
||||
InterruptCallback, this);
|
||||
|
||||
// Wait some time before powering up the ports
|
||||
if (!isRootHub)
|
||||
snooze(USB_DELAY_HUB_POWER_UP);
|
||||
@ -242,7 +244,19 @@ Hub::Explore(change_item **changeList)
|
||||
if (fPortStatus[i].status & PORT_STATUS_HIGH_SPEED)
|
||||
speed = USB_SPEED_HIGHSPEED;
|
||||
|
||||
Device *newDevice = GetBusManager()->AllocateDevice(this, i, speed);
|
||||
// either let the device inherit our addresses (if we are
|
||||
// already potentially using a transaction translator) or set
|
||||
// ourselfs as the hub when we might become the transaction
|
||||
// translator for the device.
|
||||
int8 hubAddress = HubAddress();
|
||||
uint8 hubPort = HubPort();
|
||||
if (Speed() == USB_SPEED_HIGHSPEED) {
|
||||
hubAddress = DeviceAddress();
|
||||
hubPort = i + 1;
|
||||
}
|
||||
|
||||
Device *newDevice = GetBusManager()->AllocateDevice(this,
|
||||
hubAddress, hubPort, speed);
|
||||
|
||||
if (newDevice) {
|
||||
newDevice->Changed(changeList, true);
|
||||
|
@ -180,7 +180,8 @@ virtual status_t InitCheck();
|
||||
void FreeAddress(int8 address);
|
||||
|
||||
Device *AllocateDevice(Hub *parent,
|
||||
uint8 port, usb_speed speed);
|
||||
int8 hubAddress, uint8 hubPort,
|
||||
usb_speed speed);
|
||||
void FreeDevice(Device *device);
|
||||
|
||||
virtual status_t Start();
|
||||
@ -270,6 +271,7 @@ virtual uint32 Type() { return USB_OBJECT_PIPE; };
|
||||
size_t MaxPacketSize() { return fMaxPacketSize; };
|
||||
uint8 Interval() { return fInterval; };
|
||||
|
||||
// Hub port being the one-based logical port number on the hub
|
||||
void SetHubInfo(int8 address, uint8 port);
|
||||
int8 HubAddress() { return fHubAddress; };
|
||||
uint8 HubPort() { return fHubPort; };
|
||||
@ -419,7 +421,8 @@ private:
|
||||
|
||||
class Device : public Object {
|
||||
public:
|
||||
Device(Object *parent, int8 hubPort,
|
||||
Device(Object *parent, int8 hubAddress,
|
||||
uint8 hubPort,
|
||||
usb_device_descriptor &desc,
|
||||
int8 deviceAddress,
|
||||
usb_speed speed, bool isRootHub);
|
||||
@ -464,7 +467,8 @@ virtual status_t BuildDeviceName(char *string,
|
||||
uint32 *index, size_t bufferSize,
|
||||
Device *device);
|
||||
|
||||
int8 HubPort() const { return fHubPort; };
|
||||
int8 HubAddress() const { return fHubAddress; };
|
||||
uint8 HubPort() const { return fHubPort; };
|
||||
|
||||
// Convenience functions for standard requests
|
||||
virtual status_t SetFeature(uint16 selector);
|
||||
@ -482,14 +486,16 @@ private:
|
||||
usb_configuration_info *fCurrentConfiguration;
|
||||
usb_speed fSpeed;
|
||||
int8 fDeviceAddress;
|
||||
int8 fHubPort;
|
||||
int8 fHubAddress;
|
||||
uint8 fHubPort;
|
||||
ControlPipe *fDefaultPipe;
|
||||
};
|
||||
|
||||
|
||||
class Hub : public Device {
|
||||
public:
|
||||
Hub(Object *parent, int8 hubPort,
|
||||
Hub(Object *parent, int8 hubAddress,
|
||||
uint8 hubPort,
|
||||
usb_device_descriptor &desc,
|
||||
int8 deviceAddress,
|
||||
usb_speed speed, bool isRootHub);
|
||||
|
@ -122,7 +122,7 @@ static ehci_root_hub_string_s sEHCIRootHubStrings[3] = {
|
||||
|
||||
|
||||
EHCIRootHub::EHCIRootHub(Object *rootObject, int8 deviceAddress)
|
||||
: Hub(rootObject, rootObject->GetStack()->IndexOfBusManager(rootObject->GetBusManager()),
|
||||
: Hub(rootObject, 0, rootObject->GetStack()->IndexOfBusManager(rootObject->GetBusManager()),
|
||||
sEHCIRootHubDevice, deviceAddress, USB_SPEED_HIGHSPEED, true)
|
||||
{
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ static ohci_root_hub_string_s sOHCIRootHubStrings[3] = {
|
||||
|
||||
|
||||
OHCIRootHub::OHCIRootHub(Object *rootObject, int8 deviceAddress)
|
||||
: Hub(rootObject, rootObject->GetStack()->IndexOfBusManager(rootObject->GetBusManager()),
|
||||
: Hub(rootObject, 0, rootObject->GetStack()->IndexOfBusManager(rootObject->GetBusManager()),
|
||||
sOHCIRootHubDevice, deviceAddress, USB_SPEED_FULLSPEED, true)
|
||||
{
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ static uhci_root_hub_string_s sUHCIRootHubStrings[3] = {
|
||||
|
||||
|
||||
UHCIRootHub::UHCIRootHub(Object *rootObject, int8 deviceAddress)
|
||||
: Hub(rootObject, rootObject->GetStack()->IndexOfBusManager(rootObject->GetBusManager()),
|
||||
: Hub(rootObject, 0, rootObject->GetStack()->IndexOfBusManager(rootObject->GetBusManager()),
|
||||
sUHCIRootHubDevice, deviceAddress, USB_SPEED_FULLSPEED, true)
|
||||
{
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user