diff --git a/src/add-ons/kernel/bus_managers/usb/BusManager.cpp b/src/add-ons/kernel/bus_managers/usb/BusManager.cpp index bb7c7db319..4c85750873 100644 --- a/src/add-ons/kernel/bus_managers/usb/BusManager.cpp +++ b/src/add-ons/kernel/bus_managers/usb/BusManager.cpp @@ -115,7 +115,7 @@ BusManager::FreeAddress(int8 address) Device * -BusManager::AllocateDevice(Hub *parent, usb_speed speed) +BusManager::AllocateDevice(Hub *parent, uint8 port, usb_speed speed) { // Check if there is a free entry in the device map (for the device number) int8 deviceAddress = AllocateAddress(); @@ -126,6 +126,7 @@ BusManager::AllocateDevice(Hub *parent, usb_speed speed) TRACE(("USB BusManager: setting device address to %d\n", deviceAddress)); ControlPipe *defaultPipe = _GetDefaultPipe(speed); + defaultPipe->SetHubInfo(parent->DeviceAddress(), port); if (!defaultPipe) { TRACE_ERROR(("USB BusManager: error getting the default pipe for speed %d\n", (int)speed)); @@ -162,7 +163,9 @@ BusManager::AllocateDevice(Hub *parent, usb_speed speed) snooze(USB_DELAY_SET_ADDRESS); // Create a temporary pipe with the new address - ControlPipe pipe(parent, deviceAddress, 0, speed, 8); + ControlPipe pipe(fRootObject); + pipe.InitCommon(deviceAddress, 0, speed, Pipe::Default, 8, 0, + parent->DeviceAddress(), port); // Get the device descriptor // Just retrieve the first 8 bytes of the descriptor -> minimum supported @@ -200,7 +203,7 @@ BusManager::AllocateDevice(Hub *parent, 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, deviceDescriptor, + Hub *hub = new(std::nothrow) Hub(parent, port, deviceDescriptor, deviceAddress, speed); if (!hub) { TRACE_ERROR(("USB BusManager: no memory to allocate hub\n")); @@ -219,7 +222,7 @@ BusManager::AllocateDevice(Hub *parent, usb_speed speed) } TRACE(("USB BusManager: creating new device\n")); - Device *device = new(std::nothrow) Device(parent, deviceDescriptor, + Device *device = new(std::nothrow) Device(parent, port, deviceDescriptor, deviceAddress, speed); if (!device) { TRACE_ERROR(("USB BusManager: no memory to allocate device\n")); @@ -291,8 +294,8 @@ BusManager::_GetDefaultPipe(usb_speed speed) return NULL; if (fDefaultPipes[speed] == NULL) { - fDefaultPipes[speed] = new(std::nothrow) ControlPipe(fRootObject, - 0, 0, speed, 8); + fDefaultPipes[speed] = new(std::nothrow) ControlPipe(fRootObject); + fDefaultPipes[speed]->InitCommon(0, 0, speed, Pipe::Default, 8, 0, 0, 0); } if (!fDefaultPipes[speed]) { diff --git a/src/add-ons/kernel/bus_managers/usb/Device.cpp b/src/add-ons/kernel/bus_managers/usb/Device.cpp index a0b9c5096a..3092c21066 100644 --- a/src/add-ons/kernel/bus_managers/usb/Device.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Device.cpp @@ -10,8 +10,8 @@ #include "usb_p.h" -Device::Device(Object *parent, usb_device_descriptor &desc, int8 deviceAddress, - usb_speed speed) +Device::Device(Object *parent, int8 hubPort, usb_device_descriptor &desc, + int8 deviceAddress, usb_speed speed) : Object(parent), fDeviceDescriptor(desc), fInitOK(false), @@ -19,17 +19,23 @@ Device::Device(Object *parent, usb_device_descriptor &desc, int8 deviceAddress, fConfigurations(NULL), fCurrentConfiguration(NULL), fSpeed(speed), - fDeviceAddress(deviceAddress) + fDeviceAddress(deviceAddress), + fHubPort(hubPort) { TRACE(("USB Device %d: creating device\n", fDeviceAddress)); - fDefaultPipe = new(std::nothrow) ControlPipe(this, deviceAddress, 0, - fSpeed, fDeviceDescriptor.max_packet_size_0); + fDefaultPipe = new(std::nothrow) ControlPipe(this); if (!fDefaultPipe) { TRACE_ERROR(("USB Device %d: could not allocate default pipe\n", fDeviceAddress)); 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); + // Get the device descriptor // We already have a part of it, but we want it all size_t actualLength; @@ -351,6 +357,10 @@ Device::SetConfigurationAt(uint8 index) // Set current configuration fCurrentConfiguration = &fConfigurations[index]; + int8 hubAddress = 0; + if (Parent() && (Parent()->Type() & USB_OBJECT_HUB)) + hubAddress = ((Hub *)Parent())->DeviceAddress(); + // Initialize all the endpoints that are now active for (size_t j = 0; j < fCurrentConfiguration->interface_count; j++) { usb_interface_info *interfaceInfo = fCurrentConfiguration->interface[j].active; @@ -358,35 +368,33 @@ Device::SetConfigurationAt(uint8 index) usb_endpoint_info *endpoint = &interfaceInfo->endpoint[i]; Pipe *pipe = NULL; + Pipe::pipeDirection direction = Pipe::Out; + if (endpoint->descr->endpoint_address & 0x80) + direction = Pipe::In; + switch (endpoint->descr->attributes & 0x03) { case 0x00: /* Control Endpoint */ - pipe = new(std::nothrow) ControlPipe(this, fDeviceAddress, - endpoint->descr->endpoint_address & 0x0f, fSpeed, - endpoint->descr->max_packet_size); + pipe = new(std::nothrow) ControlPipe(this); + direction = Pipe::Default; break; case 0x01: /* Isochronous Endpoint */ - pipe = new(std::nothrow) IsochronousPipe(this, fDeviceAddress, - endpoint->descr->endpoint_address & 0x0f, - (endpoint->descr->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out, - fSpeed, endpoint->descr->max_packet_size); + pipe = new(std::nothrow) IsochronousPipe(this); break; case 0x02: /* Bulk Endpoint */ - pipe = new(std::nothrow) BulkPipe(this, fDeviceAddress, - endpoint->descr->endpoint_address & 0x0f, - (endpoint->descr->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out, - fSpeed, endpoint->descr->max_packet_size); + pipe = new(std::nothrow) BulkPipe(this); break; case 0x03: /* Interrupt Endpoint */ - pipe = new(std::nothrow) InterruptPipe(this, fDeviceAddress, - endpoint->descr->endpoint_address & 0x0f, - (endpoint->descr->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out, - fSpeed, endpoint->descr->max_packet_size, endpoint->descr->interval); + pipe = new(std::nothrow) InterruptPipe(this); break; } + pipe->InitCommon(fDeviceAddress, + endpoint->descr->endpoint_address & 0x0f, + fSpeed, direction, endpoint->descr->max_packet_size, + endpoint->descr->interval, hubAddress, 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 b0b705ac1f..bb74a15eab 100644 --- a/src/add-ons/kernel/bus_managers/usb/Hub.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Hub.cpp @@ -11,9 +11,9 @@ #include -Hub::Hub(Object *parent, usb_device_descriptor &desc, int8 deviceAddress, - usb_speed speed) - : Device(parent, desc, deviceAddress, speed), +Hub::Hub(Object *parent, int8 hubPort, usb_device_descriptor &desc, + int8 deviceAddress, usb_speed speed) + : Device(parent, hubPort, desc, deviceAddress, speed), fInterruptPipe(NULL) { TRACE(("USB Hub %d: creating hub\n", DeviceAddress())); @@ -228,7 +228,7 @@ Hub::Explore(change_item **changeList) if (fPortStatus[i].status & PORT_STATUS_HIGH_SPEED) speed = USB_SPEED_HIGHSPEED; - Device *newDevice = GetBusManager()->AllocateDevice(this, speed); + Device *newDevice = GetBusManager()->AllocateDevice(this, i, speed); if (newDevice) { newDevice->Changed(changeList, true); diff --git a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp index 559e017220..9ed942dc81 100644 --- a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp @@ -10,17 +10,12 @@ #include "usb_p.h" -Pipe::Pipe(Object *parent, int8 deviceAddress, uint8 endpointAddress, - pipeDirection direction, usb_speed speed, size_t maxPacketSize) +Pipe::Pipe(Object *parent) : Object(parent), - fDeviceAddress(deviceAddress), - fEndpointAddress(endpointAddress), - fDirection(direction), - fSpeed(speed), - fMaxPacketSize(maxPacketSize), - fDataToggle(false) + fDataToggle(false), + fControllerCookie(NULL) { - GetBusManager()->NotifyPipeChange(this, USB_CHANGE_CREATED); + // all other init is to be done in InitCommon() } @@ -31,6 +26,33 @@ Pipe::~Pipe() } + + +void +Pipe::InitCommon(int8 deviceAddress, uint8 endpointAddress, usb_speed speed, + pipeDirection direction, size_t maxPacketSize, uint8 interval, + int8 hubAddress, uint8 hubPort) +{ + fDeviceAddress = deviceAddress; + fEndpointAddress = endpointAddress; + fSpeed = speed; + fDirection = direction; + fMaxPacketSize = maxPacketSize; + fHubAddress = hubAddress; + fHubPort = hubPort; + + GetBusManager()->NotifyPipeChange(this, USB_CHANGE_CREATED); +} + + +void +Pipe::SetHubInfo(int8 address, uint8 port) +{ + fHubAddress = address; + fHubPort = port; +} + + status_t Pipe::SubmitTransfer(Transfer *transfer) { @@ -100,12 +122,8 @@ Pipe::GetStatus(uint16 *status) // -InterruptPipe::InterruptPipe(Object *parent, int8 deviceAddress, - uint8 endpointAddress, pipeDirection direction, usb_speed speed, - size_t maxPacketSize, uint8 interval) - : Pipe(parent, deviceAddress, endpointAddress, direction, speed, - maxPacketSize), - fInterval(interval) +InterruptPipe::InterruptPipe(Object *parent) + : Pipe(parent) { } @@ -133,10 +151,8 @@ InterruptPipe::QueueInterrupt(void *data, size_t dataLength, // -BulkPipe::BulkPipe(Object *parent, int8 deviceAddress, uint8 endpointAddress, - pipeDirection direction, usb_speed speed, size_t maxPacketSize) - : Pipe(parent, deviceAddress, endpointAddress, direction, speed, - maxPacketSize) +BulkPipe::BulkPipe(Object *parent) + : Pipe(parent) { } @@ -182,11 +198,8 @@ BulkPipe::QueueBulkV(iovec *vector, size_t vectorCount, // -IsochronousPipe::IsochronousPipe(Object *parent, int8 deviceAddress, - uint8 endpointAddress, pipeDirection direction, usb_speed speed, - size_t maxPacketSize) - : Pipe(parent, deviceAddress, endpointAddress, direction, speed, - maxPacketSize), +IsochronousPipe::IsochronousPipe(Object *parent) + : Pipe(parent), fMaxQueuedPackets(0), fMaxBufferDuration(0), fSampleSize(0) @@ -273,10 +286,8 @@ typedef struct transfer_result_data_s { } transfer_result_data; -ControlPipe::ControlPipe(Object *parent, int8 deviceAddress, - uint8 endpointAddress, usb_speed speed, size_t maxPacketSize) - : Pipe(parent, deviceAddress, endpointAddress, Default, speed, - maxPacketSize) +ControlPipe::ControlPipe(Object *parent) + : Pipe(parent) { } 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 f99762fccb..bc763c2dfb 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb_p.h +++ b/src/add-ons/kernel/bus_managers/usb/usb_p.h @@ -179,7 +179,7 @@ virtual status_t InitCheck(); void FreeAddress(int8 address); Device *AllocateDevice(Hub *parent, - usb_speed speed); + uint8 port, usb_speed speed); void FreeDevice(Device *device); virtual status_t Start(); @@ -249,21 +249,29 @@ class Pipe : public Object { public: enum pipeDirection { In, Out, Default }; - Pipe(Object *parent, - int8 deviceAddress, - uint8 endpointAddress, - pipeDirection direction, - usb_speed speed, - size_t maxPacketSize); + Pipe(Object *parent); virtual ~Pipe(); + void InitCommon(int8 deviceAddress, + uint8 endpointAddress, + usb_speed speed, + pipeDirection direction, + size_t maxPacketSize, + uint8 interval, + int8 hubAddress, uint8 hubPort); + virtual uint32 Type() { return USB_OBJECT_PIPE; }; int8 DeviceAddress() { return fDeviceAddress; }; usb_speed Speed() { return fSpeed; }; pipeDirection Direction() { return fDirection; }; - int8 EndpointAddress() { return fEndpointAddress; }; + uint8 EndpointAddress() { return fEndpointAddress; }; size_t MaxPacketSize() { return fMaxPacketSize; }; + uint8 Interval() { return fInterval; }; + + void SetHubInfo(int8 address, uint8 port); + int8 HubAddress() { return fHubAddress; }; + uint8 HubPort() { return fHubPort; }; virtual bool DataToggle() { return fDataToggle; }; virtual void SetDataToggle(bool toggle) { fDataToggle = toggle; }; @@ -285,6 +293,9 @@ private: pipeDirection fDirection; usb_speed fSpeed; size_t fMaxPacketSize; + uint8 fInterval; + int8 fHubAddress; + uint8 fHubPort; bool fDataToggle; void *fControllerCookie; }; @@ -292,11 +303,7 @@ private: class ControlPipe : public Pipe { public: - ControlPipe(Object *parent, - int8 deviceAddress, - uint8 endpointAddress, - usb_speed speed, - size_t maxPacketSize); + ControlPipe(Object *parent); virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE; }; @@ -328,13 +335,7 @@ static void SendRequestCallback(void *cookie, class InterruptPipe : public Pipe { public: - InterruptPipe(Object *parent, - int8 deviceAddress, - uint8 endpointAddress, - pipeDirection direction, - usb_speed speed, - size_t maxPacketSize, - uint8 interval); + InterruptPipe(Object *parent); virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_INTERRUPT_PIPE; }; @@ -342,22 +343,12 @@ virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_INTERRUPT_PIPE size_t dataLength, usb_callback_func callback, void *callbackCookie); - - uint8 Interval() { return fInterval; }; - -private: - uint8 fInterval; }; class BulkPipe : public Pipe { public: - BulkPipe(Object *parent, - int8 deviceAddress, - uint8 endpointAddress, - pipeDirection direction, - usb_speed speed, - size_t maxPacketSize); + BulkPipe(Object *parent); virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_BULK_PIPE; }; @@ -374,12 +365,7 @@ virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_BULK_PIPE; }; class IsochronousPipe : public Pipe { public: - IsochronousPipe(Object *parent, - int8 deviceAddress, - uint8 endpointAddress, - pipeDirection direction, - usb_speed speed, - size_t maxPacketSize); + IsochronousPipe(Object *parent); virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_ISO_PIPE; }; @@ -425,7 +411,7 @@ private: class Device : public Object { public: - Device(Object *parent, + Device(Object *parent, int8 hubPort, usb_device_descriptor &desc, int8 deviceAddress, usb_speed speed); @@ -447,6 +433,7 @@ virtual status_t GetDescriptor(uint8 descriptorType, int8 DeviceAddress() const { return fDeviceAddress; }; const usb_device_descriptor *DeviceDescriptor() const; + usb_speed Speed() const { return fSpeed; }; const usb_configuration_info *Configuration() const; const usb_configuration_info *ConfigurationAt(uint8 index) const; @@ -464,6 +451,8 @@ virtual status_t BuildDeviceName(char *string, uint32 *index, size_t bufferSize, Device *device); + int8 HubPort() const { return fHubPort; }; + // Convenience functions for standard requests virtual status_t SetFeature(uint16 selector); virtual status_t ClearFeature(uint16 selector); @@ -479,13 +468,14 @@ private: usb_configuration_info *fCurrentConfiguration; usb_speed fSpeed; int8 fDeviceAddress; + int8 fHubPort; ControlPipe *fDefaultPipe; }; class Hub : public Device { public: - Hub(Object *parent, + Hub(Object *parent, int8 hubPort, usb_device_descriptor &desc, int8 deviceAddress, usb_speed speed); diff --git a/src/add-ons/kernel/busses/usb/ehci_rh.cpp b/src/add-ons/kernel/busses/usb/ehci_rh.cpp index 9ea157a659..2d5f3480a1 100644 --- a/src/add-ons/kernel/busses/usb/ehci_rh.cpp +++ b/src/add-ons/kernel/busses/usb/ehci_rh.cpp @@ -122,7 +122,8 @@ static ehci_root_hub_string_s sEHCIRootHubStrings[3] = { EHCIRootHub::EHCIRootHub(Object *rootObject, int8 deviceAddress) - : Hub(rootObject, sEHCIRootHubDevice, deviceAddress, USB_SPEED_HIGHSPEED) + : Hub(rootObject, rootObject->GetStack()->IndexOfBusManager(rootObject->GetBusManager()), + sEHCIRootHubDevice, deviceAddress, USB_SPEED_HIGHSPEED) { } diff --git a/src/add-ons/kernel/busses/usb/ohci_rh.cpp b/src/add-ons/kernel/busses/usb/ohci_rh.cpp index 5d3fd1e623..117c11601a 100644 --- a/src/add-ons/kernel/busses/usb/ohci_rh.cpp +++ b/src/add-ons/kernel/busses/usb/ohci_rh.cpp @@ -121,7 +121,8 @@ static ohci_root_hub_string_s sOHCIRootHubStrings[3] = { OHCIRootHub::OHCIRootHub(Object *rootObject, int8 deviceAddress) - : Hub(rootObject, sOHCIRootHubDevice, deviceAddress, USB_SPEED_FULLSPEED) + : Hub(rootObject, rootObject->GetStack()->IndexOfBusManager(rootObject->GetBusManager()), + sOHCIRootHubDevice, deviceAddress, USB_SPEED_FULLSPEED) { } diff --git a/src/add-ons/kernel/busses/usb/uhci_rh.cpp b/src/add-ons/kernel/busses/usb/uhci_rh.cpp index e1df67824c..e6c4cff1e6 100644 --- a/src/add-ons/kernel/busses/usb/uhci_rh.cpp +++ b/src/add-ons/kernel/busses/usb/uhci_rh.cpp @@ -126,7 +126,8 @@ static uhci_root_hub_string_s sUHCIRootHubStrings[3] = { UHCIRootHub::UHCIRootHub(Object *rootObject, int8 deviceAddress) - : Hub(rootObject, sUHCIRootHubDevice, deviceAddress, USB_SPEED_FULLSPEED) + : Hub(rootObject, rootObject->GetStack()->IndexOfBusManager(rootObject->GetBusManager()), + sUHCIRootHubDevice, deviceAddress, USB_SPEED_FULLSPEED) { }