* 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
This commit is contained in:
Michael Lotz 2007-11-21 19:15:16 +00:00
parent 349ba1a53c
commit 072c28ded5
8 changed files with 115 additions and 100 deletions

View File

@ -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]) {

View File

@ -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();
}
}

View File

@ -11,9 +11,9 @@
#include <stdio.h>
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);

View File

@ -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)
{
}

View File

@ -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);

View File

@ -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)
{
}

View File

@ -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)
{
}

View File

@ -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)
{
}