* 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:
@@ -112,7 +112,8 @@ BusManager::FreeAddress(int8 address)
|
|||||||
|
|
||||||
|
|
||||||
Device *
|
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)
|
// Check if there is a free entry in the device map (for the device number)
|
||||||
int8 deviceAddress = AllocateAddress();
|
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));
|
TRACE(("USB BusManager: setting device address to %d\n", deviceAddress));
|
||||||
ControlPipe *defaultPipe = _GetDefaultPipe(speed);
|
ControlPipe *defaultPipe = _GetDefaultPipe(speed);
|
||||||
defaultPipe->SetHubInfo(parent->DeviceAddress(), port);
|
defaultPipe->SetHubInfo(hubAddress, hubPort);
|
||||||
|
|
||||||
if (!defaultPipe) {
|
if (!defaultPipe) {
|
||||||
TRACE_ERROR(("USB BusManager: error getting the default pipe for speed %d\n", (int)speed));
|
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
|
// Create a temporary pipe with the new address
|
||||||
ControlPipe pipe(fRootObject);
|
ControlPipe pipe(fRootObject);
|
||||||
pipe.InitCommon(deviceAddress, 0, speed, Pipe::Default, 8, 0,
|
pipe.InitCommon(deviceAddress, 0, speed, Pipe::Default, 8, 0, hubAddress,
|
||||||
parent->DeviceAddress(), port);
|
hubPort);
|
||||||
|
|
||||||
// Get the device descriptor
|
// Get the device descriptor
|
||||||
// Just retrieve the first 8 bytes of the descriptor -> minimum supported
|
// 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)
|
// Create a new instance based on the type (Hub or Device)
|
||||||
if (deviceDescriptor.device_class == 0x09) {
|
if (deviceDescriptor.device_class == 0x09) {
|
||||||
TRACE(("USB BusManager: creating new hub\n"));
|
TRACE(("USB BusManager: creating new hub\n"));
|
||||||
Hub *hub = new(std::nothrow) Hub(parent, port, deviceDescriptor,
|
Hub *hub = new(std::nothrow) Hub(parent, hubAddress, hubPort,
|
||||||
deviceAddress, speed, false);
|
deviceDescriptor, deviceAddress, speed, false);
|
||||||
if (!hub) {
|
if (!hub) {
|
||||||
TRACE_ERROR(("USB BusManager: no memory to allocate hub\n"));
|
TRACE_ERROR(("USB BusManager: no memory to allocate hub\n"));
|
||||||
FreeAddress(deviceAddress);
|
FreeAddress(deviceAddress);
|
||||||
@@ -219,8 +220,8 @@ BusManager::AllocateDevice(Hub *parent, uint8 port, usb_speed speed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
TRACE(("USB BusManager: creating new device\n"));
|
TRACE(("USB BusManager: creating new device\n"));
|
||||||
Device *device = new(std::nothrow) Device(parent, port, deviceDescriptor,
|
Device *device = new(std::nothrow) Device(parent, hubAddress, hubPort,
|
||||||
deviceAddress, speed, false);
|
deviceDescriptor, deviceAddress, speed, false);
|
||||||
if (!device) {
|
if (!device) {
|
||||||
TRACE_ERROR(("USB BusManager: no memory to allocate device\n"));
|
TRACE_ERROR(("USB BusManager: no memory to allocate device\n"));
|
||||||
FreeAddress(deviceAddress);
|
FreeAddress(deviceAddress);
|
||||||
|
|||||||
@@ -10,8 +10,9 @@
|
|||||||
#include "usb_p.h"
|
#include "usb_p.h"
|
||||||
|
|
||||||
|
|
||||||
Device::Device(Object *parent, int8 hubPort, usb_device_descriptor &desc,
|
Device::Device(Object *parent, int8 hubAddress, uint8 hubPort,
|
||||||
int8 deviceAddress, usb_speed speed, bool isRootHub)
|
usb_device_descriptor &desc, int8 deviceAddress, usb_speed speed,
|
||||||
|
bool isRootHub)
|
||||||
: Object(parent),
|
: Object(parent),
|
||||||
fDeviceDescriptor(desc),
|
fDeviceDescriptor(desc),
|
||||||
fInitOK(false),
|
fInitOK(false),
|
||||||
@@ -21,6 +22,7 @@ Device::Device(Object *parent, int8 hubPort, usb_device_descriptor &desc,
|
|||||||
fCurrentConfiguration(NULL),
|
fCurrentConfiguration(NULL),
|
||||||
fSpeed(speed),
|
fSpeed(speed),
|
||||||
fDeviceAddress(deviceAddress),
|
fDeviceAddress(deviceAddress),
|
||||||
|
fHubAddress(hubAddress),
|
||||||
fHubPort(hubPort)
|
fHubPort(hubPort)
|
||||||
{
|
{
|
||||||
TRACE(("USB Device %d: creating device\n", fDeviceAddress));
|
TRACE(("USB Device %d: creating device\n", fDeviceAddress));
|
||||||
@@ -31,11 +33,8 @@ Device::Device(Object *parent, int8 hubPort, usb_device_descriptor &desc,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8 hubAddress = 0;
|
|
||||||
if (parent->Type() & USB_OBJECT_HUB)
|
|
||||||
hubAddress = ((Hub *)parent)->DeviceAddress();
|
|
||||||
fDefaultPipe->InitCommon(fDeviceAddress, 0, fSpeed, Pipe::Default,
|
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
|
// Get the device descriptor
|
||||||
// We already have a part of it, but we want it all
|
// We already have a part of it, but we want it all
|
||||||
@@ -436,10 +435,6 @@ Device::SetConfigurationAt(uint8 index)
|
|||||||
void
|
void
|
||||||
Device::InitEndpoints(int32 interfaceIndex)
|
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++) {
|
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;
|
||||||
@@ -475,7 +470,7 @@ Device::InitEndpoints(int32 interfaceIndex)
|
|||||||
pipe->InitCommon(fDeviceAddress,
|
pipe->InitCommon(fDeviceAddress,
|
||||||
endpoint->descr->endpoint_address & 0x0f,
|
endpoint->descr->endpoint_address & 0x0f,
|
||||||
fSpeed, direction, endpoint->descr->max_packet_size,
|
fSpeed, direction, endpoint->descr->max_packet_size,
|
||||||
endpoint->descr->interval, hubAddress, fHubPort);
|
endpoint->descr->interval, fHubAddress, fHubPort);
|
||||||
endpoint->handle = pipe->USBID();
|
endpoint->handle = pipe->USBID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,11 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
Hub::Hub(Object *parent, int8 hubPort, usb_device_descriptor &desc,
|
Hub::Hub(Object *parent, int8 hubAddress, uint8 hubPort,
|
||||||
int8 deviceAddress, usb_speed speed, bool isRootHub)
|
usb_device_descriptor &desc, int8 deviceAddress, usb_speed speed,
|
||||||
: Device(parent, hubPort, desc, deviceAddress, speed, isRootHub),
|
bool isRootHub)
|
||||||
|
: Device(parent, hubAddress, hubPort, desc, deviceAddress, speed,
|
||||||
|
isRootHub),
|
||||||
fInterruptPipe(NULL)
|
fInterruptPipe(NULL)
|
||||||
{
|
{
|
||||||
TRACE(("USB Hub %d: creating hub\n", DeviceAddress()));
|
TRACE(("USB Hub %d: creating hub\n", DeviceAddress()));
|
||||||
@@ -61,15 +63,15 @@ Hub::Hub(Object *parent, int8 hubPort, usb_device_descriptor &desc,
|
|||||||
fHubDescriptor.num_ports = USB_MAX_PORT_COUNT;
|
fHubDescriptor.num_ports = USB_MAX_PORT_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object *object = GetStack()->GetObject(Configuration()->interface->active->endpoint[0].handle);
|
usb_interface_list *list = Configuration()->interface;
|
||||||
if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) {
|
Object *object = GetStack()->GetObject(list->active->endpoint[0].handle);
|
||||||
TRACE_ERROR(("USB Hub %d: no interrupt pipe found\n", DeviceAddress()));
|
if (object && (object->Type() & USB_OBJECT_INTERRUPT_PIPE) != 0) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fInterruptPipe = (InterruptPipe *)object;
|
fInterruptPipe = (InterruptPipe *)object;
|
||||||
fInterruptPipe->QueueInterrupt(fInterruptStatus, sizeof(fInterruptStatus),
|
fInterruptPipe->QueueInterrupt(fInterruptStatus,
|
||||||
InterruptCallback, this);
|
sizeof(fInterruptStatus), InterruptCallback, this);
|
||||||
|
} else {
|
||||||
|
TRACE_ERROR(("USB Hub %d: no interrupt pipe found\n", DeviceAddress()));
|
||||||
|
}
|
||||||
|
|
||||||
// Wait some time before powering up the ports
|
// Wait some time before powering up the ports
|
||||||
if (!isRootHub)
|
if (!isRootHub)
|
||||||
@@ -242,7 +244,19 @@ Hub::Explore(change_item **changeList)
|
|||||||
if (fPortStatus[i].status & PORT_STATUS_HIGH_SPEED)
|
if (fPortStatus[i].status & PORT_STATUS_HIGH_SPEED)
|
||||||
speed = USB_SPEED_HIGHSPEED;
|
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) {
|
if (newDevice) {
|
||||||
newDevice->Changed(changeList, true);
|
newDevice->Changed(changeList, true);
|
||||||
|
|||||||
@@ -180,7 +180,8 @@ virtual status_t InitCheck();
|
|||||||
void FreeAddress(int8 address);
|
void FreeAddress(int8 address);
|
||||||
|
|
||||||
Device *AllocateDevice(Hub *parent,
|
Device *AllocateDevice(Hub *parent,
|
||||||
uint8 port, usb_speed speed);
|
int8 hubAddress, uint8 hubPort,
|
||||||
|
usb_speed speed);
|
||||||
void FreeDevice(Device *device);
|
void FreeDevice(Device *device);
|
||||||
|
|
||||||
virtual status_t Start();
|
virtual status_t Start();
|
||||||
@@ -270,6 +271,7 @@ virtual uint32 Type() { return USB_OBJECT_PIPE; };
|
|||||||
size_t MaxPacketSize() { return fMaxPacketSize; };
|
size_t MaxPacketSize() { return fMaxPacketSize; };
|
||||||
uint8 Interval() { return fInterval; };
|
uint8 Interval() { return fInterval; };
|
||||||
|
|
||||||
|
// Hub port being the one-based logical port number on the hub
|
||||||
void SetHubInfo(int8 address, uint8 port);
|
void SetHubInfo(int8 address, uint8 port);
|
||||||
int8 HubAddress() { return fHubAddress; };
|
int8 HubAddress() { return fHubAddress; };
|
||||||
uint8 HubPort() { return fHubPort; };
|
uint8 HubPort() { return fHubPort; };
|
||||||
@@ -419,7 +421,8 @@ private:
|
|||||||
|
|
||||||
class Device : public Object {
|
class Device : public Object {
|
||||||
public:
|
public:
|
||||||
Device(Object *parent, int8 hubPort,
|
Device(Object *parent, int8 hubAddress,
|
||||||
|
uint8 hubPort,
|
||||||
usb_device_descriptor &desc,
|
usb_device_descriptor &desc,
|
||||||
int8 deviceAddress,
|
int8 deviceAddress,
|
||||||
usb_speed speed, bool isRootHub);
|
usb_speed speed, bool isRootHub);
|
||||||
@@ -464,7 +467,8 @@ virtual status_t BuildDeviceName(char *string,
|
|||||||
uint32 *index, size_t bufferSize,
|
uint32 *index, size_t bufferSize,
|
||||||
Device *device);
|
Device *device);
|
||||||
|
|
||||||
int8 HubPort() const { return fHubPort; };
|
int8 HubAddress() const { return fHubAddress; };
|
||||||
|
uint8 HubPort() const { return fHubPort; };
|
||||||
|
|
||||||
// Convenience functions for standard requests
|
// Convenience functions for standard requests
|
||||||
virtual status_t SetFeature(uint16 selector);
|
virtual status_t SetFeature(uint16 selector);
|
||||||
@@ -482,14 +486,16 @@ private:
|
|||||||
usb_configuration_info *fCurrentConfiguration;
|
usb_configuration_info *fCurrentConfiguration;
|
||||||
usb_speed fSpeed;
|
usb_speed fSpeed;
|
||||||
int8 fDeviceAddress;
|
int8 fDeviceAddress;
|
||||||
int8 fHubPort;
|
int8 fHubAddress;
|
||||||
|
uint8 fHubPort;
|
||||||
ControlPipe *fDefaultPipe;
|
ControlPipe *fDefaultPipe;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Hub : public Device {
|
class Hub : public Device {
|
||||||
public:
|
public:
|
||||||
Hub(Object *parent, int8 hubPort,
|
Hub(Object *parent, int8 hubAddress,
|
||||||
|
uint8 hubPort,
|
||||||
usb_device_descriptor &desc,
|
usb_device_descriptor &desc,
|
||||||
int8 deviceAddress,
|
int8 deviceAddress,
|
||||||
usb_speed speed, bool isRootHub);
|
usb_speed speed, bool isRootHub);
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ static ehci_root_hub_string_s sEHCIRootHubStrings[3] = {
|
|||||||
|
|
||||||
|
|
||||||
EHCIRootHub::EHCIRootHub(Object *rootObject, int8 deviceAddress)
|
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)
|
sEHCIRootHubDevice, deviceAddress, USB_SPEED_HIGHSPEED, true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ static ohci_root_hub_string_s sOHCIRootHubStrings[3] = {
|
|||||||
|
|
||||||
|
|
||||||
OHCIRootHub::OHCIRootHub(Object *rootObject, int8 deviceAddress)
|
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)
|
sOHCIRootHubDevice, deviceAddress, USB_SPEED_FULLSPEED, true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ static uhci_root_hub_string_s sUHCIRootHubStrings[3] = {
|
|||||||
|
|
||||||
|
|
||||||
UHCIRootHub::UHCIRootHub(Object *rootObject, int8 deviceAddress)
|
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)
|
sUHCIRootHubDevice, deviceAddress, USB_SPEED_FULLSPEED, true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user