diff --git a/src/add-ons/kernel/bus_managers/usb/BusManager.cpp b/src/add-ons/kernel/bus_managers/usb/BusManager.cpp index 09e494257e..f52a08906e 100644 --- a/src/add-ons/kernel/bus_managers/usb/BusManager.cpp +++ b/src/add-ons/kernel/bus_managers/usb/BusManager.cpp @@ -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); diff --git a/src/add-ons/kernel/bus_managers/usb/Device.cpp b/src/add-ons/kernel/bus_managers/usb/Device.cpp index 1b1766914c..2f3c068195 100644 --- a/src/add-ons/kernel/bus_managers/usb/Device.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Device.cpp @@ -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(); } } diff --git a/src/add-ons/kernel/bus_managers/usb/Hub.cpp b/src/add-ons/kernel/bus_managers/usb/Hub.cpp index 3208dea380..76295a66db 100644 --- a/src/add-ons/kernel/bus_managers/usb/Hub.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Hub.cpp @@ -11,9 +11,11 @@ #include -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); 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 67f7dc1443..c4cb8b95c7 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb_p.h +++ b/src/add-ons/kernel/bus_managers/usb/usb_p.h @@ -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); diff --git a/src/add-ons/kernel/busses/usb/ehci_rh.cpp b/src/add-ons/kernel/busses/usb/ehci_rh.cpp index 98167d6c01..bab00e9d58 100644 --- a/src/add-ons/kernel/busses/usb/ehci_rh.cpp +++ b/src/add-ons/kernel/busses/usb/ehci_rh.cpp @@ -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) { } diff --git a/src/add-ons/kernel/busses/usb/ohci_rh.cpp b/src/add-ons/kernel/busses/usb/ohci_rh.cpp index b88b46e705..a7c3cdebde 100644 --- a/src/add-ons/kernel/busses/usb/ohci_rh.cpp +++ b/src/add-ons/kernel/busses/usb/ohci_rh.cpp @@ -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) { } diff --git a/src/add-ons/kernel/busses/usb/uhci_rh.cpp b/src/add-ons/kernel/busses/usb/uhci_rh.cpp index 3492f6e2ea..d1a8525a56 100644 --- a/src/add-ons/kernel/busses/usb/uhci_rh.cpp +++ b/src/add-ons/kernel/busses/usb/uhci_rh.cpp @@ -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) { }