From 072c28ded529ca52c32863b4eb1b8f21f1debb71 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Wed, 21 Nov 2007 19:15:16 +0000 Subject: [PATCH] * Redesign the Pipe constructor to only take the parent object * All other init is done in InitCommon() which only needs to be present in the base class * Adding the hub port a device is attached to to the Device class * Add hub port and hub address to the Pipe class (will be used for split transactions in EHCI) * Update the root hubs to reflect the changes to hub creation Sadly we need pipes that do not belong to devices (default pipe for addressing and to get initial device descriptor). Therefore we cannot resolve hub address and port from the parent device. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22972 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/bus_managers/usb/BusManager.cpp | 15 ++-- .../kernel/bus_managers/usb/Device.cpp | 48 +++++++------ src/add-ons/kernel/bus_managers/usb/Hub.cpp | 8 +-- src/add-ons/kernel/bus_managers/usb/Pipe.cpp | 67 ++++++++++-------- src/add-ons/kernel/bus_managers/usb/usb_p.h | 68 ++++++++----------- src/add-ons/kernel/busses/usb/ehci_rh.cpp | 3 +- src/add-ons/kernel/busses/usb/ohci_rh.cpp | 3 +- src/add-ons/kernel/busses/usb/uhci_rh.cpp | 3 +- 8 files changed, 115 insertions(+), 100 deletions(-) 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) { }