* Rewrote some stack internals (again). Everything is now created using a parent object that shares the BusManager and Stack information to reduce individual constructors.

* Don't inherit Device and Interface from pipes anymore. The device has a default pipe member now.
* Since the parent of each Object is now known, we can send control messages using the default pipe of the device from all attached elements (pipes and interfaces).
* Fixed the generic {Set|Clear}Feature() and GetStatus() calls to include the endpoint address for pipe specific requests.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18710 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2006-08-30 17:59:23 +00:00
parent 1c1c6688d1
commit 8fedfdfcf8
15 changed files with 275 additions and 210 deletions

View File

@ -15,7 +15,6 @@ BusManager::BusManager(Stack *stack)
fDefaultPipe(NULL),
fDefaultPipeLowSpeed(NULL),
fRootHub(NULL),
fStack(stack),
fExploreThread(-1)
{
if (benaphore_init(&fLock, "usb busmanager lock") < B_OK) {
@ -23,16 +22,22 @@ BusManager::BusManager(Stack *stack)
return;
}
fRootObject = new(std::nothrow) Object(stack, this);
if (!fRootObject)
return;
// Clear the device map
for (int32 i = 0; i < 128; i++)
fDeviceMap[i] = false;
// Set up the default pipes
fDefaultPipe = new(std::nothrow) ControlPipe(this, 0, Pipe::FullSpeed, 0, 8);
fDefaultPipe = new(std::nothrow) ControlPipe(fRootObject, 0, 0,
Pipe::FullSpeed, 8);
if (!fDefaultPipe)
return;
fDefaultPipeLowSpeed = new(std::nothrow) ControlPipe(this, 0, Pipe::LowSpeed, 0, 8);
fDefaultPipeLowSpeed = new(std::nothrow) ControlPipe(fRootObject, 0, 0,
Pipe::LowSpeed, 8);
if (!fDefaultPipeLowSpeed)
return;
@ -92,8 +97,28 @@ BusManager::ExploreThread(void *data)
}
int8
BusManager::AllocateAddress()
{
if (!Lock())
return -1;
int8 deviceAddress = -1;
for (int32 i = 1; i < 128; i++) {
if (fDeviceMap[i] == false) {
deviceAddress = i;
fDeviceMap[i] = true;
break;
}
}
Unlock();
return deviceAddress;
}
Device *
BusManager::AllocateNewDevice(Device *parent, bool lowSpeed)
BusManager::AllocateNewDevice(Hub *parent, bool lowSpeed)
{
// Check if there is a free entry in the device map (for the device number)
int8 deviceAddress = AllocateAddress();
@ -103,7 +128,6 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed)
}
TRACE(("usb BusManager::AllocateNewDevice(): setting device address to %d\n", deviceAddress));
ControlPipe *defaultPipe = (lowSpeed ? fDefaultPipeLowSpeed : fDefaultPipe);
status_t result = B_ERROR;
@ -134,8 +158,8 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed)
snooze(USB_DELAY_SET_ADDRESS);
// Create a temporary pipe with the new address
ControlPipe pipe(this, deviceAddress,
lowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed, 0, 8);
ControlPipe pipe(parent, deviceAddress, 0,
lowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed, 8);
// Get the device descriptor
// Just retrieve the first 8 bytes of the descriptor -> minimum supported
@ -172,7 +196,7 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed)
// Create a new instance based on the type (Hub or Device)
if (deviceDescriptor.device_class == 0x09) {
TRACE(("usb BusManager::AllocateNewDevice(): creating new hub\n"));
Hub *hub = new(std::nothrow) Hub(this, parent, deviceDescriptor,
Hub *hub = new(std::nothrow) Hub(parent, deviceDescriptor,
deviceAddress, lowSpeed);
if (!hub) {
TRACE_ERROR(("usb BusManager::AllocateNewDevice(): no memory to allocate hub\n"));
@ -185,16 +209,11 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed)
return NULL;
}
if (parent == NULL) {
// root hub
fRootHub = hub;
}
return (Device *)hub;
}
TRACE(("usb BusManager::AllocateNewDevice(): creating new device\n"));
Device *device = new(std::nothrow) Device(this, parent, deviceDescriptor,
Device *device = new(std::nothrow) Device(parent, deviceDescriptor,
deviceAddress, lowSpeed);
if (!device) {
TRACE_ERROR(("usb BusManager::AllocateNewDevice(): no memory to allocate device\n"));
@ -211,26 +230,6 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed)
}
int8
BusManager::AllocateAddress()
{
if (!Lock())
return -1;
int8 deviceAddress = -1;
for (int32 i = 1; i < 128; i++) {
if (fDeviceMap[i] == false) {
deviceAddress = i;
fDeviceMap[i] = true;
break;
}
}
Unlock();
return deviceAddress;
}
status_t
BusManager::Start()
{

View File

@ -10,17 +10,14 @@
#include "usb_p.h"
Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc,
int8 deviceAddress, bool lowSpeed)
: ControlPipe(bus, deviceAddress,
lowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed, 0,
desc.max_packet_size_0),
Device::Device(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
bool lowSpeed)
: Object(parent),
fDeviceDescriptor(desc),
fInitOK(false),
fConfigurations(NULL),
fCurrentConfiguration(NULL),
fInitOK(false),
fLowSpeed(lowSpeed),
fParent(parent),
fDeviceAddress(deviceAddress),
fLock(-1),
fNotifyCookie(NULL)
@ -35,6 +32,14 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc,
set_sem_owner(fLock, B_SYSTEM_TEAM);
fDefaultPipe = new(std::nothrow) ControlPipe(this, deviceAddress, 0,
fLowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed,
fDeviceDescriptor.max_packet_size_0);
if (!fDefaultPipe) {
TRACE_ERROR(("USB Device: could not allocate default pipe\n"));
return;
}
fMaxPacketIn[0] = fMaxPacketOut[0] = fDeviceDescriptor.max_packet_size_0;
// Get the device descriptor
@ -146,8 +151,7 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc,
interfaceInfo->generic_count = 0;
interfaceInfo->generic = NULL;
Interface *interface = new(std::nothrow) Interface(GetBusManager(),
fDeviceAddress, Speed());
Interface *interface = new(std::nothrow) Interface(this);
interfaceInfo->handle = interface->USBID();
currentInterface = interfaceInfo;
@ -182,36 +186,37 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc,
Pipe *endpoint = NULL;
switch (endpointDescriptor->attributes & 0x03) {
case 0x00: /* Control Endpoint */
endpoint = new(std::nothrow) ControlPipe(GetBusManager(),
fDeviceAddress, Speed(),
endpoint = new(std::nothrow) ControlPipe(this,
fDeviceAddress,
endpointDescriptor->endpoint_address & 0x0f,
fLowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed,
endpointDescriptor->max_packet_size);
break;
case 0x01: /* Isochronous Endpoint */
endpoint = new(std::nothrow) IsochronousPipe(GetBusManager(),
endpoint = new(std::nothrow) IsochronousPipe(this,
fDeviceAddress,
endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out,
Speed(),
endpointDescriptor->endpoint_address & 0x0f,
(endpointDescriptor->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out,
fLowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed,
endpointDescriptor->max_packet_size);
break;
case 0x02: /* Bulk Endpoint */
endpoint = new(std::nothrow) BulkPipe(GetBusManager(),
endpoint = new(std::nothrow) BulkPipe(this,
fDeviceAddress,
endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out,
Speed(),
endpointDescriptor->endpoint_address & 0x0f,
(endpointDescriptor->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out,
fLowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed,
endpointDescriptor->max_packet_size);
break;
case 0x03: /* Interrupt Endpoint */
endpoint = new(std::nothrow) InterruptPipe(GetBusManager(),
endpoint = new(std::nothrow) InterruptPipe(this,
fDeviceAddress,
endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out,
Speed(),
endpointDescriptor->endpoint_address & 0x0f,
(endpointDescriptor->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out,
fLowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed,
endpointDescriptor->max_packet_size);
break;
}
@ -271,7 +276,7 @@ status_t
Device::GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID,
void *data, size_t dataLength, size_t *actualLength)
{
return SendRequest(
return fDefaultPipe->SendRequest(
USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD, // type
USB_REQUEST_GET_DESCRIPTOR, // request
(descriptorType << 8) | index, // value
@ -318,7 +323,7 @@ Device::SetConfigurationAt(uint8 index)
if (index >= fDeviceDescriptor.num_configurations)
return B_BAD_VALUE;
status_t result = SendRequest(
status_t result = fDefaultPipe->SendRequest(
USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD, // type
USB_REQUEST_SET_CONFIGURATION, // request
fConfigurations[index].descr->configuration_value, // value
@ -410,10 +415,10 @@ status_t
Device::BuildDeviceName(char *string, uint32 *index, size_t bufferSize,
Device *device)
{
if (!fParent)
if (!Parent() || (Parent()->Type() & USB_OBJECT_HUB) == 0)
return B_ERROR;
fParent->BuildDeviceName(string, index, bufferSize, this);
((Hub *)Parent())->BuildDeviceName(string, index, bufferSize, this);
return B_OK;
}
@ -421,7 +426,7 @@ Device::BuildDeviceName(char *string, uint32 *index, size_t bufferSize,
status_t
Device::SetFeature(uint16 selector)
{
return SendRequest(
return fDefaultPipe->SendRequest(
USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT,
USB_REQUEST_SET_FEATURE,
selector,
@ -436,7 +441,7 @@ Device::SetFeature(uint16 selector)
status_t
Device::ClearFeature(uint16 selector)
{
return SendRequest(
return fDefaultPipe->SendRequest(
USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT,
USB_REQUEST_CLEAR_FEATURE,
selector,
@ -451,7 +456,7 @@ Device::ClearFeature(uint16 selector)
status_t
Device::GetStatus(uint16 *status)
{
return SendRequest(
return fDefaultPipe->SendRequest(
USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_IN,
USB_REQUEST_GET_STATUS,
0,

View File

@ -11,9 +11,9 @@
#include <stdio.h>
Hub::Hub(BusManager *bus, Device *parent, usb_device_descriptor &desc,
int8 deviceAddress, bool lowSpeed)
: Device(bus, parent, desc, deviceAddress, lowSpeed)
Hub::Hub(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
bool lowSpeed)
: Device(parent, desc, deviceAddress, lowSpeed)
{
TRACE(("USB Hub is being initialised\n"));
@ -68,7 +68,7 @@ Hub::Hub(BusManager *bus, Device *parent, usb_device_descriptor &desc,
// Enable port power on all ports
for (int32 i = 0; i < fHubDescriptor.num_ports; i++) {
status = SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
status = DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
USB_REQUEST_SET_FEATURE, PORT_POWER, i + 1, 0, NULL, 0, NULL);
if (status < B_OK)
@ -88,7 +88,7 @@ Hub::UpdatePortStatus(uint8 index)
{
// get the current port status
size_t actualLength = 0;
status_t result = SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_IN,
status_t result = DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_IN,
USB_REQUEST_GET_STATUS, 0, index + 1, 4, (void *)&fPortStatus[index],
4, &actualLength);
@ -104,7 +104,7 @@ Hub::UpdatePortStatus(uint8 index)
status_t
Hub::ResetPort(uint8 index)
{
status_t result = SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
status_t result = DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
USB_REQUEST_SET_FEATURE, PORT_RESET, index + 1, 0, NULL, 0, NULL);
if (result < B_OK)
@ -135,7 +135,7 @@ Hub::ResetPort(uint8 index)
}
// clear the reset change
result = SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
result = DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
USB_REQUEST_CLEAR_FEATURE, C_PORT_RESET, index + 1, 0, NULL, 0, NULL);
if (result < B_OK)
return result;
@ -155,9 +155,7 @@ Hub::Explore()
if (result < B_OK)
continue;
if (DeviceAddress() > 1)
TRACE(("USB Hub (%d): port %d: status: 0x%04x; change: 0x%04x\n", DeviceAddress(), i, fPortStatus[i].status, fPortStatus[i].change));
TRACE(("USB Hub (%d): port %d: status: 0x%04x; change: 0x%04x\n", DeviceAddress(), i, fPortStatus[i].status, fPortStatus[i].change));
if (fPortStatus[i].change & PORT_STATUS_CONNECTION) {
if (fPortStatus[i].status & PORT_STATUS_CONNECTION) {
// new device attached!
@ -190,7 +188,7 @@ Hub::Explore()
// the device failed to setup correctly, disable the port
// so that the device doesn't get in the way of future
// addressing.
SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
USB_REQUEST_CLEAR_FEATURE, PORT_ENABLE, i + 1,
0, NULL, 0, NULL);
}
@ -199,14 +197,13 @@ Hub::Explore()
TRACE(("USB Hub Explore(): Device removed\n"));
if (fChildren[i]) {
GetStack()->NotifyDeviceChange(fChildren[i], false);
GetStack()->PutUSBID(fChildren[i]->USBID());
delete fChildren[i];
fChildren[i] = NULL;
}
}
// clear status change
SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
USB_REQUEST_CLEAR_FEATURE, C_PORT_CONNECTION, i + 1,
0, NULL, 0, NULL);
}
@ -234,7 +231,7 @@ status_t
Hub::GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID,
void *data, size_t dataLength, size_t *actualLength)
{
return SendRequest(
return DefaultPipe()->SendRequest(
USB_REQTYPE_DEVICE_IN | USB_REQTYPE_CLASS, // type
USB_REQUEST_GET_DESCRIPTOR, // request
(descriptorType << 8) | index, // value

View File

@ -9,8 +9,8 @@
#include "usb_p.h"
Interface::Interface(BusManager *bus, int8 deviceAddress, pipeSpeed speed)
: ControlPipe(bus, deviceAddress, speed, 0, 8)
Interface::Interface(Object *parent)
: Object(parent)
{
}
@ -18,7 +18,7 @@ Interface::Interface(BusManager *bus, int8 deviceAddress, pipeSpeed speed)
status_t
Interface::SetFeature(uint16 selector)
{
return SendRequest(
return ((Device *)Parent())->DefaultPipe()->SendRequest(
USB_REQTYPE_STANDARD | USB_REQTYPE_INTERFACE_OUT,
USB_REQUEST_SET_FEATURE,
selector,
@ -33,7 +33,7 @@ Interface::SetFeature(uint16 selector)
status_t
Interface::ClearFeature(uint16 selector)
{
return SendRequest(
return ((Device *)Parent())->DefaultPipe()->SendRequest(
USB_REQTYPE_STANDARD | USB_REQTYPE_INTERFACE_OUT,
USB_REQUEST_CLEAR_FEATURE,
selector,
@ -48,7 +48,7 @@ Interface::ClearFeature(uint16 selector)
status_t
Interface::GetStatus(uint16 *status)
{
return SendRequest(
return ((Device *)Parent())->DefaultPipe()->SendRequest(
USB_REQTYPE_STANDARD | USB_REQTYPE_INTERFACE_IN,
USB_REQUEST_GET_STATUS,
0,

View File

@ -9,9 +9,52 @@
#include "usb_p.h"
Object::Object(BusManager *bus)
: fBusManager(bus),
fStack(bus->GetStack()),
Object::Object(Stack *stack, BusManager *bus)
: fParent(NULL),
fBusManager(bus),
fStack(stack),
fUSBID(fStack->GetUSBID(this))
{
}
Object::Object(Object *parent)
: fParent(parent),
fBusManager(parent->GetBusManager()),
fStack(parent->GetStack()),
fUSBID(fStack->GetUSBID(this))
{
}
Object::~Object()
{
fStack->PutUSBID(fUSBID);
}
status_t
Object::SetFeature(uint16 selector)
{
// to be implemented in subclasses
TRACE_ERROR(("USB Object: set feature called\n"));
return B_ERROR;
}
status_t
Object::ClearFeature(uint16 selector)
{
// to be implemented in subclasses
TRACE_ERROR(("USB Object: clear feature called\n"));
return B_ERROR;
}
status_t
Object::GetStatus(uint16 *status)
{
// to be implemented in subclasses
TRACE_ERROR(("USB Object: get status called\n"));
return B_ERROR;
}

View File

@ -10,9 +10,9 @@
#include "usb_p.h"
Pipe::Pipe(BusManager *bus, int8 deviceAddress, pipeDirection direction,
pipeSpeed speed, uint8 endpointAddress, size_t maxPacketSize)
: Object(bus),
Pipe::Pipe(Object *parent, int8 deviceAddress, uint8 endpointAddress,
pipeDirection direction, pipeSpeed speed, size_t maxPacketSize)
: Object(parent),
fDeviceAddress(deviceAddress),
fEndpointAddress(endpointAddress),
fDirection(direction),
@ -43,15 +43,60 @@ Pipe::CancelQueuedTransfers()
}
status_t
Pipe::SetFeature(uint16 selector)
{
return ((Device *)Parent())->DefaultPipe()->SendRequest(
USB_REQTYPE_STANDARD | USB_REQTYPE_ENDPOINT_OUT,
USB_REQUEST_SET_FEATURE,
selector,
fEndpointAddress,
0,
NULL,
0,
NULL);
}
status_t
Pipe::ClearFeature(uint16 selector)
{
return ((Device *)Parent())->DefaultPipe()->SendRequest(
USB_REQTYPE_STANDARD | USB_REQTYPE_ENDPOINT_OUT,
USB_REQUEST_CLEAR_FEATURE,
selector,
fEndpointAddress,
0,
NULL,
0,
NULL);
}
status_t
Pipe::GetStatus(uint16 *status)
{
return ((Device *)Parent())->DefaultPipe()->SendRequest(
USB_REQTYPE_STANDARD | USB_REQTYPE_ENDPOINT_IN,
USB_REQUEST_GET_STATUS,
0,
fEndpointAddress,
2,
(void *)status,
2,
NULL);
}
//
// #pragma mark -
//
InterruptPipe::InterruptPipe(BusManager *bus, int8 deviceAddress,
pipeDirection direction, pipeSpeed speed, uint8 endpointAddress,
InterruptPipe::InterruptPipe(Object *parent, int8 deviceAddress,
uint8 endpointAddress, pipeDirection direction, pipeSpeed speed,
size_t maxPacketSize)
: Pipe(bus, deviceAddress, direction, speed, endpointAddress,
: Pipe(parent, deviceAddress, endpointAddress, direction, speed,
maxPacketSize)
{
}
@ -80,10 +125,9 @@ InterruptPipe::QueueInterrupt(void *data, size_t dataLength,
//
BulkPipe::BulkPipe(BusManager *bus, int8 deviceAddress,
pipeDirection direction, pipeSpeed speed, uint8 endpointAddress,
size_t maxPacketSize)
: Pipe(bus, deviceAddress, direction, speed, endpointAddress,
BulkPipe::BulkPipe(Object *parent, int8 deviceAddress, uint8 endpointAddress,
pipeDirection direction, pipeSpeed speed, size_t maxPacketSize)
: Pipe(parent, deviceAddress, endpointAddress, direction, speed,
maxPacketSize)
{
}
@ -130,10 +174,10 @@ BulkPipe::QueueBulkV(iovec *vector, size_t vectorCount,
//
IsochronousPipe::IsochronousPipe(BusManager *bus, int8 deviceAddress,
pipeDirection direction, pipeSpeed speed, uint8 endpointAddress,
IsochronousPipe::IsochronousPipe(Object *parent, int8 deviceAddress,
uint8 endpointAddress, pipeDirection direction, pipeSpeed speed,
size_t maxPacketSize)
: Pipe(bus, deviceAddress, direction, speed, endpointAddress,
: Pipe(parent, deviceAddress, endpointAddress, direction, speed,
maxPacketSize)
{
}
@ -154,16 +198,17 @@ IsochronousPipe::QueueIsochronous(void *data, size_t dataLength,
//
struct transfer_result_data {
typedef struct transfer_result_data_s {
sem_id notify_sem;
uint32 status;
size_t actual_length;
};
} transfer_result_data;
ControlPipe::ControlPipe(BusManager *bus, int8 deviceAddress, pipeSpeed speed,
uint8 endpointAddress, size_t maxPacketSize)
: Pipe(bus, deviceAddress, Default, speed, endpointAddress, maxPacketSize)
ControlPipe::ControlPipe(Object *parent, int8 deviceAddress,
uint8 endpointAddress, pipeSpeed speed, size_t maxPacketSize)
: Pipe(parent, deviceAddress, endpointAddress, Default, speed,
maxPacketSize)
{
}
@ -241,48 +286,3 @@ ControlPipe::QueueRequest(uint8 requestType, uint8 request, uint16 value,
delete transfer;
return result;
}
status_t
ControlPipe::SetFeature(uint16 selector)
{
return SendRequest(
USB_REQTYPE_STANDARD | USB_REQTYPE_ENDPOINT_OUT,
USB_REQUEST_SET_FEATURE,
selector,
0,
0,
NULL,
0,
NULL);
}
status_t
ControlPipe::ClearFeature(uint16 selector)
{
return SendRequest(
USB_REQTYPE_STANDARD | USB_REQTYPE_ENDPOINT_OUT,
USB_REQUEST_CLEAR_FEATURE,
selector,
0,
0,
NULL,
0,
NULL);
}
status_t
ControlPipe::GetStatus(uint16 *status)
{
return SendRequest(
USB_REQTYPE_STANDARD | USB_REQTYPE_ENDPOINT_IN,
USB_REQUEST_GET_STATUS,
0,
0,
2,
(void *)status,
2,
NULL);
}

View File

@ -7,6 +7,7 @@
* Niels S. Reedijk
*/
#define TRACE_USB
#include <util/kernel_cpp.h>
#include "usb_p.h"
#include <USB_rle.h>
@ -146,10 +147,10 @@ set_feature(usb_id handle, uint16 selector)
{
TRACE(("usb_module: set_feature(0x%08x, %d)\n", handle, selector));
Object *object = gUSBStack->GetObject(handle);
if (!object || (object->Type() & USB_OBJECT_CONTROL_PIPE) == 0)
if (!object)
return B_BAD_VALUE;
return ((ControlPipe *)object)->SetFeature(selector);
return object->SetFeature(selector);
}
@ -158,10 +159,10 @@ clear_feature(usb_id handle, uint16 selector)
{
TRACE(("usb_module: clear_feature(0x%08x, %d)\n", handle, selector));
Object *object = gUSBStack->GetObject(handle);
if (!object || (object->Type() & USB_OBJECT_CONTROL_PIPE) == 0)
if (!object)
return B_BAD_VALUE;
return ((ControlPipe *)object)->ClearFeature(selector);
return object->ClearFeature(selector);
}
@ -173,10 +174,10 @@ get_status(usb_id handle, uint16 *status)
return B_BAD_VALUE;
Object *object = gUSBStack->GetObject(handle);
if (!object || (object->Type() & USB_OBJECT_CONTROL_PIPE) == 0)
if (!object)
return B_BAD_VALUE;
return ((ControlPipe *)object)->GetStatus(status);
return object->GetStatus(status);
}
@ -203,8 +204,8 @@ send_request(usb_device device, uint8 requestType, uint8 request,
if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
return B_BAD_VALUE;
return ((Device *)object)->SendRequest(requestType, request, value, index,
length, data, length, actualLength);
return ((Device *)object)->DefaultPipe()->SendRequest(requestType, request,
value, index, length, data, length, actualLength);
}
@ -218,8 +219,8 @@ queue_request(usb_device device, uint8 requestType, uint8 request,
if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
return B_BAD_VALUE;
return ((Device *)object)->QueueRequest(requestType, request, value, index,
length, data, length, callback, callbackCookie);
return ((Device *)object)->DefaultPipe()->QueueRequest(requestType,
request, value, index, length, data, length, callback, callbackCookie);
}

View File

@ -138,18 +138,16 @@ virtual status_t InitCheck();
bool Lock();
void Unlock();
Device *AllocateNewDevice(Device *parent,
bool lowSpeed);
int8 AllocateAddress();
Device *AllocateNewDevice(Hub *parent,
bool lowSpeed);
virtual status_t Start();
virtual status_t Stop();
virtual status_t SubmitTransfer(Transfer *transfer);
Stack *GetStack() { return fStack; };
void SetStack(Stack *stack) { fStack = stack; };
Object *RootObject() { return fRootObject; };
Hub *GetRootHub() { return fRootHub; };
void SetRootHub(Hub *hub) { fRootHub = hub; };
@ -165,14 +163,18 @@ static int32 ExploreThread(void *data);
ControlPipe *fDefaultPipe;
ControlPipe *fDefaultPipeLowSpeed;
Hub *fRootHub;
Stack *fStack;
thread_id fExploreThread;
Object *fRootObject;
};
class Object {
public:
Object(BusManager *bus);
Object(Stack *stack, BusManager *bus);
Object(Object *parent);
virtual ~Object();
Object *Parent() { return fParent; };
BusManager *GetBusManager() { return fBusManager; };
Stack *GetStack() { return fStack; };
@ -180,7 +182,13 @@ public:
usb_id USBID() { return fUSBID; };
virtual uint32 Type() { return USB_OBJECT_NONE; };
// Convenience functions for standard requests
virtual status_t SetFeature(uint16 selector);
virtual status_t ClearFeature(uint16 selector);
virtual status_t GetStatus(uint16 *status);
private:
Object *fParent;
BusManager *fBusManager;
Stack *fStack;
usb_id fUSBID;
@ -196,11 +204,11 @@ public:
enum pipeDirection { In, Out, Default };
enum pipeSpeed { LowSpeed, FullSpeed, HighSpeed };
Pipe(BusManager *bus,
Pipe(Object *parent,
int8 deviceAddress,
uint8 endpointAddress,
pipeDirection direction,
pipeSpeed speed,
uint8 endpointAddress,
size_t maxPacketSize);
virtual ~Pipe();
@ -218,7 +226,12 @@ virtual void SetDataToggle(bool toggle) { fDataToggle = toggle; };
status_t SubmitTransfer(Transfer *transfer);
status_t CancelQueuedTransfers();
protected:
// Convenience functions for standard requests
virtual status_t SetFeature(uint16 selector);
virtual status_t ClearFeature(uint16 selector);
virtual status_t GetStatus(uint16 *status);
private:
int8 fDeviceAddress;
uint8 fEndpointAddress;
pipeDirection fDirection;
@ -230,10 +243,10 @@ protected:
class ControlPipe : public Pipe {
public:
ControlPipe(BusManager *bus,
ControlPipe(Object *parent,
int8 deviceAddress,
pipeSpeed speed,
uint8 endpointAddress,
pipeSpeed speed,
size_t maxPacketSize);
virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE; };
@ -261,21 +274,16 @@ static void SendRequestCallback(void *cookie,
void *data, size_t dataLength,
usb_callback_func callback,
void *callbackCookie);
// Convenience functions for standard requests
virtual status_t SetFeature(uint16 selector);
virtual status_t ClearFeature(uint16 selector);
virtual status_t GetStatus(uint16 *status);
};
class InterruptPipe : public Pipe {
public:
InterruptPipe(BusManager *bus,
InterruptPipe(Object *parent,
int8 deviceAddress,
uint8 endpointAddress,
pipeDirection direction,
pipeSpeed speed,
uint8 endpointAddress,
size_t maxPacketSize);
virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_INTERRUPT_PIPE; };
@ -289,11 +297,11 @@ virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_INTERRUPT_PIPE
class BulkPipe : public Pipe {
public:
BulkPipe(BusManager *bus,
BulkPipe(Object *parent,
int8 deviceAddress,
uint8 endpointAddress,
pipeDirection direction,
pipeSpeed speed,
uint8 endpointAddress,
size_t maxPacketSize);
virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_BULK_PIPE; };
@ -311,11 +319,11 @@ virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_BULK_PIPE; };
class IsochronousPipe : public Pipe {
public:
IsochronousPipe(BusManager *bus,
IsochronousPipe(Object *parent,
int8 deviceAddress,
uint8 endpointAddress,
pipeDirection direction,
pipeSpeed speed,
uint8 endpointAddress,
size_t maxPacketSize);
virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_ISO_PIPE; };
@ -331,13 +339,11 @@ virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_ISO_PIPE; };
};
class Interface : public ControlPipe {
class Interface : public Object {
public:
Interface(BusManager *bus,
int8 deviceAddress,
pipeSpeed speed);
Interface(Object *parent);
virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE | USB_OBJECT_INTERFACE; };
virtual uint32 Type() { return USB_OBJECT_INTERFACE; };
// Convenience functions for standard requests
virtual status_t SetFeature(uint16 selector);
@ -346,15 +352,17 @@ virtual status_t GetStatus(uint16 *status);
};
class Device : public ControlPipe {
class Device : public Object {
public:
Device(BusManager *bus, Device *parent,
Device(Object *parent,
usb_device_descriptor &desc,
int8 deviceAddress, bool lowSpeed);
status_t InitCheck();
virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE | USB_OBJECT_DEVICE; };
virtual uint32 Type() { return USB_OBJECT_DEVICE; };
ControlPipe *DefaultPipe() { return fDefaultPipe; };
virtual status_t GetDescriptor(uint8 descriptorType,
uint8 index, uint16 languageID,
@ -384,26 +392,28 @@ virtual status_t GetStatus(uint16 *status);
protected:
usb_device_descriptor fDeviceDescriptor;
bool fInitOK;
private:
usb_configuration_info *fConfigurations;
usb_configuration_info *fCurrentConfiguration;
bool fInitOK;
bool fLowSpeed;
Device *fParent;
int8 fDeviceAddress;
size_t fMaxPacketIn[16];
size_t fMaxPacketOut[16];
sem_id fLock;
void *fNotifyCookie;
ControlPipe *fDefaultPipe;
};
class Hub : public Device {
public:
Hub(BusManager *bus, Device *parent,
Hub(Object *parent,
usb_device_descriptor &desc,
int8 deviceAddress, bool lowSpeed);
virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE | USB_OBJECT_DEVICE | USB_OBJECT_HUB; };
virtual uint32 Type() { return USB_OBJECT_DEVICE | USB_OBJECT_HUB; };
virtual status_t GetDescriptor(uint8 descriptorType,
uint8 index, uint16 languageID,

View File

@ -202,7 +202,7 @@ EHCI::Start()
}
fRootHubAddress = AllocateAddress();
fRootHub = new(std::nothrow) EHCIRootHub(this, fRootHubAddress);
fRootHub = new(std::nothrow) EHCIRootHub(RootObject(), fRootHubAddress);
if (!fRootHub) {
TRACE_ERROR(("usb_ehci: no memory to allocate root hub\n"));
return B_NO_MEMORY;

View File

@ -134,7 +134,8 @@ static pci_module_info *sPCIModule;
class EHCIRootHub : public Hub {
public:
EHCIRootHub(EHCI *ehci, int8 deviceAddress);
EHCIRootHub(Object *rootObject,
int8 deviceAddress);
static status_t ProcessTransfer(EHCI *ehci,
Transfer *transfer);

View File

@ -95,27 +95,34 @@ static ehci_root_hub_string_s sEHCIRootHubStrings[3] = {
{
4, // Descriptor length
USB_DESCRIPTOR_STRING, // Descriptor type
0x0409 // Supported language IDs (English US)
{
0x0409 // Supported language IDs (English US)
}
},
{
12, // Descriptor length
USB_DESCRIPTOR_STRING, // Descriptor type
'H', 'A', 'I', 'K', 'U', ' ', // Characters
'I', 'n', 'c', '.'
{
'H', 'A', 'I', 'K', 'U', // Characters
' ', 'I', 'n', 'c', '.'
}
},
{
26, // Descriptor length
USB_DESCRIPTOR_STRING, // Descriptor type
'E', 'H', 'C', 'I', ' ', 'R', // Characters
'o', 'o', 't', 'H', 'u', 'b'
{
'E', 'H', 'C', 'I', ' ', // Characters
'R', 'o', 'o', 't', 'H',
'u', 'b'
}
}
};
EHCIRootHub::EHCIRootHub(EHCI *ehci, int8 deviceAddress)
: Hub(ehci, NULL, sEHCIRootHubDevice, deviceAddress, false)
EHCIRootHub::EHCIRootHub(Object *rootObject, int8 deviceAddress)
: Hub(rootObject, sEHCIRootHubDevice, deviceAddress, false)
{
}

View File

@ -88,7 +88,7 @@ usb_hub_descriptor ohci_hubd =
//Implementation
OHCIRootHub::OHCIRootHub( OHCI *ohci , int8 devicenum )
: Hub( ohci , NULL , ohci_devd , devicenum , false )
: Hub( ohci->RootObject() , ohci_devd , devicenum , false )
{
m_ohci = ohci;
}

View File

@ -483,7 +483,7 @@ UHCI::Start()
}
fRootHubAddress = AllocateAddress();
fRootHub = new(std::nothrow) UHCIRootHub(this, fRootHubAddress);
fRootHub = new(std::nothrow) UHCIRootHub(RootObject(), fRootHubAddress);
if (!fRootHub) {
TRACE_ERROR(("usb_uhci: no memory to allocate root hub\n"));
return B_NO_MEMORY;

View File

@ -161,7 +161,8 @@ static pci_module_info *sPCIModule;
class UHCIRootHub : public Hub {
public:
UHCIRootHub(UHCI *uhci, int8 deviceAddress);
UHCIRootHub(Object *rootObject,
int8 deviceAddress);
static status_t ProcessTransfer(UHCI *uhci,
Transfer *transfer);

View File

@ -99,7 +99,7 @@ static uhci_root_hub_string_s sUHCIRootHubStrings[3] = {
4, // Descriptor length
USB_DESCRIPTOR_STRING, // Descriptor type
{
0x0409 // Supported language IDs (English US)
0x0409 // Supported language IDs (English US)
}
},
@ -107,8 +107,8 @@ static uhci_root_hub_string_s sUHCIRootHubStrings[3] = {
12, // Descriptor length
USB_DESCRIPTOR_STRING, // Descriptor type
{
'H', 'A', 'I', 'K', 'U', ' ', // Characters
'I', 'n', 'c', '.'
'H', 'A', 'I', 'K', 'U', // Characters
' ', 'I', 'n', 'c', '.'
}
},
@ -117,15 +117,16 @@ static uhci_root_hub_string_s sUHCIRootHubStrings[3] = {
26, // Descriptor length
USB_DESCRIPTOR_STRING, // Descriptor type
{
'U', 'H', 'C', 'I', ' ', 'R', // Characters
'o', 'o', 't', 'H', 'u', 'b'
'U', 'H', 'C', 'I', ' ', // Characters
'R', 'o', 'o', 't', 'H',
'u', 'b'
}
}
};
UHCIRootHub::UHCIRootHub(UHCI *uhci, int8 deviceAddress)
: Hub(uhci, NULL, sUHCIRootHubDevice, deviceAddress, false)
UHCIRootHub::UHCIRootHub(Object *rootObject, int8 deviceAddress)
: Hub(rootObject, sUHCIRootHubDevice, deviceAddress, false)
{
}