* 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:
@@ -15,7 +15,6 @@ BusManager::BusManager(Stack *stack)
|
|||||||
fDefaultPipe(NULL),
|
fDefaultPipe(NULL),
|
||||||
fDefaultPipeLowSpeed(NULL),
|
fDefaultPipeLowSpeed(NULL),
|
||||||
fRootHub(NULL),
|
fRootHub(NULL),
|
||||||
fStack(stack),
|
|
||||||
fExploreThread(-1)
|
fExploreThread(-1)
|
||||||
{
|
{
|
||||||
if (benaphore_init(&fLock, "usb busmanager lock") < B_OK) {
|
if (benaphore_init(&fLock, "usb busmanager lock") < B_OK) {
|
||||||
@@ -23,16 +22,22 @@ BusManager::BusManager(Stack *stack)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fRootObject = new(std::nothrow) Object(stack, this);
|
||||||
|
if (!fRootObject)
|
||||||
|
return;
|
||||||
|
|
||||||
// Clear the device map
|
// Clear the device map
|
||||||
for (int32 i = 0; i < 128; i++)
|
for (int32 i = 0; i < 128; i++)
|
||||||
fDeviceMap[i] = false;
|
fDeviceMap[i] = false;
|
||||||
|
|
||||||
// Set up the default pipes
|
// 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)
|
if (!fDefaultPipe)
|
||||||
return;
|
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)
|
if (!fDefaultPipeLowSpeed)
|
||||||
return;
|
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 *
|
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)
|
// Check if there is a free entry in the device map (for the device number)
|
||||||
int8 deviceAddress = AllocateAddress();
|
int8 deviceAddress = AllocateAddress();
|
||||||
@@ -103,7 +128,6 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
TRACE(("usb BusManager::AllocateNewDevice(): setting device address to %d\n", deviceAddress));
|
TRACE(("usb BusManager::AllocateNewDevice(): setting device address to %d\n", deviceAddress));
|
||||||
|
|
||||||
ControlPipe *defaultPipe = (lowSpeed ? fDefaultPipeLowSpeed : fDefaultPipe);
|
ControlPipe *defaultPipe = (lowSpeed ? fDefaultPipeLowSpeed : fDefaultPipe);
|
||||||
|
|
||||||
status_t result = B_ERROR;
|
status_t result = B_ERROR;
|
||||||
@@ -134,8 +158,8 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed)
|
|||||||
snooze(USB_DELAY_SET_ADDRESS);
|
snooze(USB_DELAY_SET_ADDRESS);
|
||||||
|
|
||||||
// Create a temporary pipe with the new address
|
// Create a temporary pipe with the new address
|
||||||
ControlPipe pipe(this, deviceAddress,
|
ControlPipe pipe(parent, deviceAddress, 0,
|
||||||
lowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed, 0, 8);
|
lowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed, 8);
|
||||||
|
|
||||||
// Get the device descriptor
|
// Get the device descriptor
|
||||||
// Just retrieve the first 8 bytes of the descriptor -> minimum supported
|
// 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)
|
// Create a new instance based on the type (Hub or Device)
|
||||||
if (deviceDescriptor.device_class == 0x09) {
|
if (deviceDescriptor.device_class == 0x09) {
|
||||||
TRACE(("usb BusManager::AllocateNewDevice(): creating new hub\n"));
|
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);
|
deviceAddress, lowSpeed);
|
||||||
if (!hub) {
|
if (!hub) {
|
||||||
TRACE_ERROR(("usb BusManager::AllocateNewDevice(): no memory to allocate hub\n"));
|
TRACE_ERROR(("usb BusManager::AllocateNewDevice(): no memory to allocate hub\n"));
|
||||||
@@ -185,16 +209,11 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent == NULL) {
|
|
||||||
// root hub
|
|
||||||
fRootHub = hub;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (Device *)hub;
|
return (Device *)hub;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE(("usb BusManager::AllocateNewDevice(): creating new device\n"));
|
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);
|
deviceAddress, lowSpeed);
|
||||||
if (!device) {
|
if (!device) {
|
||||||
TRACE_ERROR(("usb BusManager::AllocateNewDevice(): no memory to allocate device\n"));
|
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
|
status_t
|
||||||
BusManager::Start()
|
BusManager::Start()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,17 +10,14 @@
|
|||||||
#include "usb_p.h"
|
#include "usb_p.h"
|
||||||
|
|
||||||
|
|
||||||
Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc,
|
Device::Device(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
|
||||||
int8 deviceAddress, bool lowSpeed)
|
bool lowSpeed)
|
||||||
: ControlPipe(bus, deviceAddress,
|
: Object(parent),
|
||||||
lowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed, 0,
|
|
||||||
desc.max_packet_size_0),
|
|
||||||
fDeviceDescriptor(desc),
|
fDeviceDescriptor(desc),
|
||||||
|
fInitOK(false),
|
||||||
fConfigurations(NULL),
|
fConfigurations(NULL),
|
||||||
fCurrentConfiguration(NULL),
|
fCurrentConfiguration(NULL),
|
||||||
fInitOK(false),
|
|
||||||
fLowSpeed(lowSpeed),
|
fLowSpeed(lowSpeed),
|
||||||
fParent(parent),
|
|
||||||
fDeviceAddress(deviceAddress),
|
fDeviceAddress(deviceAddress),
|
||||||
fLock(-1),
|
fLock(-1),
|
||||||
fNotifyCookie(NULL)
|
fNotifyCookie(NULL)
|
||||||
@@ -35,6 +32,14 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc,
|
|||||||
|
|
||||||
set_sem_owner(fLock, B_SYSTEM_TEAM);
|
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;
|
fMaxPacketIn[0] = fMaxPacketOut[0] = fDeviceDescriptor.max_packet_size_0;
|
||||||
|
|
||||||
// Get the device descriptor
|
// Get the device descriptor
|
||||||
@@ -146,8 +151,7 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc,
|
|||||||
interfaceInfo->generic_count = 0;
|
interfaceInfo->generic_count = 0;
|
||||||
interfaceInfo->generic = NULL;
|
interfaceInfo->generic = NULL;
|
||||||
|
|
||||||
Interface *interface = new(std::nothrow) Interface(GetBusManager(),
|
Interface *interface = new(std::nothrow) Interface(this);
|
||||||
fDeviceAddress, Speed());
|
|
||||||
interfaceInfo->handle = interface->USBID();
|
interfaceInfo->handle = interface->USBID();
|
||||||
|
|
||||||
currentInterface = interfaceInfo;
|
currentInterface = interfaceInfo;
|
||||||
@@ -182,36 +186,37 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc,
|
|||||||
Pipe *endpoint = NULL;
|
Pipe *endpoint = NULL;
|
||||||
switch (endpointDescriptor->attributes & 0x03) {
|
switch (endpointDescriptor->attributes & 0x03) {
|
||||||
case 0x00: /* Control Endpoint */
|
case 0x00: /* Control Endpoint */
|
||||||
endpoint = new(std::nothrow) ControlPipe(GetBusManager(),
|
endpoint = new(std::nothrow) ControlPipe(this,
|
||||||
fDeviceAddress, Speed(),
|
fDeviceAddress,
|
||||||
endpointDescriptor->endpoint_address & 0x0f,
|
endpointDescriptor->endpoint_address & 0x0f,
|
||||||
|
fLowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed,
|
||||||
endpointDescriptor->max_packet_size);
|
endpointDescriptor->max_packet_size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x01: /* Isochronous Endpoint */
|
case 0x01: /* Isochronous Endpoint */
|
||||||
endpoint = new(std::nothrow) IsochronousPipe(GetBusManager(),
|
endpoint = new(std::nothrow) IsochronousPipe(this,
|
||||||
fDeviceAddress,
|
fDeviceAddress,
|
||||||
endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out,
|
|
||||||
Speed(),
|
|
||||||
endpointDescriptor->endpoint_address & 0x0f,
|
endpointDescriptor->endpoint_address & 0x0f,
|
||||||
|
(endpointDescriptor->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out,
|
||||||
|
fLowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed,
|
||||||
endpointDescriptor->max_packet_size);
|
endpointDescriptor->max_packet_size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x02: /* Bulk Endpoint */
|
case 0x02: /* Bulk Endpoint */
|
||||||
endpoint = new(std::nothrow) BulkPipe(GetBusManager(),
|
endpoint = new(std::nothrow) BulkPipe(this,
|
||||||
fDeviceAddress,
|
fDeviceAddress,
|
||||||
endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out,
|
|
||||||
Speed(),
|
|
||||||
endpointDescriptor->endpoint_address & 0x0f,
|
endpointDescriptor->endpoint_address & 0x0f,
|
||||||
|
(endpointDescriptor->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out,
|
||||||
|
fLowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed,
|
||||||
endpointDescriptor->max_packet_size);
|
endpointDescriptor->max_packet_size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x03: /* Interrupt Endpoint */
|
case 0x03: /* Interrupt Endpoint */
|
||||||
endpoint = new(std::nothrow) InterruptPipe(GetBusManager(),
|
endpoint = new(std::nothrow) InterruptPipe(this,
|
||||||
fDeviceAddress,
|
fDeviceAddress,
|
||||||
endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out,
|
|
||||||
Speed(),
|
|
||||||
endpointDescriptor->endpoint_address & 0x0f,
|
endpointDescriptor->endpoint_address & 0x0f,
|
||||||
|
(endpointDescriptor->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out,
|
||||||
|
fLowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed,
|
||||||
endpointDescriptor->max_packet_size);
|
endpointDescriptor->max_packet_size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -271,7 +276,7 @@ status_t
|
|||||||
Device::GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID,
|
Device::GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID,
|
||||||
void *data, size_t dataLength, size_t *actualLength)
|
void *data, size_t dataLength, size_t *actualLength)
|
||||||
{
|
{
|
||||||
return SendRequest(
|
return fDefaultPipe->SendRequest(
|
||||||
USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD, // type
|
USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD, // type
|
||||||
USB_REQUEST_GET_DESCRIPTOR, // request
|
USB_REQUEST_GET_DESCRIPTOR, // request
|
||||||
(descriptorType << 8) | index, // value
|
(descriptorType << 8) | index, // value
|
||||||
@@ -318,7 +323,7 @@ Device::SetConfigurationAt(uint8 index)
|
|||||||
if (index >= fDeviceDescriptor.num_configurations)
|
if (index >= fDeviceDescriptor.num_configurations)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
status_t result = SendRequest(
|
status_t result = fDefaultPipe->SendRequest(
|
||||||
USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD, // type
|
USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD, // type
|
||||||
USB_REQUEST_SET_CONFIGURATION, // request
|
USB_REQUEST_SET_CONFIGURATION, // request
|
||||||
fConfigurations[index].descr->configuration_value, // value
|
fConfigurations[index].descr->configuration_value, // value
|
||||||
@@ -410,10 +415,10 @@ status_t
|
|||||||
Device::BuildDeviceName(char *string, uint32 *index, size_t bufferSize,
|
Device::BuildDeviceName(char *string, uint32 *index, size_t bufferSize,
|
||||||
Device *device)
|
Device *device)
|
||||||
{
|
{
|
||||||
if (!fParent)
|
if (!Parent() || (Parent()->Type() & USB_OBJECT_HUB) == 0)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
fParent->BuildDeviceName(string, index, bufferSize, this);
|
((Hub *)Parent())->BuildDeviceName(string, index, bufferSize, this);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,7 +426,7 @@ Device::BuildDeviceName(char *string, uint32 *index, size_t bufferSize,
|
|||||||
status_t
|
status_t
|
||||||
Device::SetFeature(uint16 selector)
|
Device::SetFeature(uint16 selector)
|
||||||
{
|
{
|
||||||
return SendRequest(
|
return fDefaultPipe->SendRequest(
|
||||||
USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT,
|
USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT,
|
||||||
USB_REQUEST_SET_FEATURE,
|
USB_REQUEST_SET_FEATURE,
|
||||||
selector,
|
selector,
|
||||||
@@ -436,7 +441,7 @@ Device::SetFeature(uint16 selector)
|
|||||||
status_t
|
status_t
|
||||||
Device::ClearFeature(uint16 selector)
|
Device::ClearFeature(uint16 selector)
|
||||||
{
|
{
|
||||||
return SendRequest(
|
return fDefaultPipe->SendRequest(
|
||||||
USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT,
|
USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT,
|
||||||
USB_REQUEST_CLEAR_FEATURE,
|
USB_REQUEST_CLEAR_FEATURE,
|
||||||
selector,
|
selector,
|
||||||
@@ -451,7 +456,7 @@ Device::ClearFeature(uint16 selector)
|
|||||||
status_t
|
status_t
|
||||||
Device::GetStatus(uint16 *status)
|
Device::GetStatus(uint16 *status)
|
||||||
{
|
{
|
||||||
return SendRequest(
|
return fDefaultPipe->SendRequest(
|
||||||
USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_IN,
|
USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_IN,
|
||||||
USB_REQUEST_GET_STATUS,
|
USB_REQUEST_GET_STATUS,
|
||||||
0,
|
0,
|
||||||
|
|||||||
@@ -11,9 +11,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
Hub::Hub(BusManager *bus, Device *parent, usb_device_descriptor &desc,
|
Hub::Hub(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
|
||||||
int8 deviceAddress, bool lowSpeed)
|
bool lowSpeed)
|
||||||
: Device(bus, parent, desc, deviceAddress, lowSpeed)
|
: Device(parent, desc, deviceAddress, lowSpeed)
|
||||||
{
|
{
|
||||||
TRACE(("USB Hub is being initialised\n"));
|
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
|
// Enable port power on all ports
|
||||||
for (int32 i = 0; i < fHubDescriptor.num_ports; i++) {
|
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);
|
USB_REQUEST_SET_FEATURE, PORT_POWER, i + 1, 0, NULL, 0, NULL);
|
||||||
|
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
@@ -88,7 +88,7 @@ Hub::UpdatePortStatus(uint8 index)
|
|||||||
{
|
{
|
||||||
// get the current port status
|
// get the current port status
|
||||||
size_t actualLength = 0;
|
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],
|
USB_REQUEST_GET_STATUS, 0, index + 1, 4, (void *)&fPortStatus[index],
|
||||||
4, &actualLength);
|
4, &actualLength);
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ Hub::UpdatePortStatus(uint8 index)
|
|||||||
status_t
|
status_t
|
||||||
Hub::ResetPort(uint8 index)
|
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);
|
USB_REQUEST_SET_FEATURE, PORT_RESET, index + 1, 0, NULL, 0, NULL);
|
||||||
|
|
||||||
if (result < B_OK)
|
if (result < B_OK)
|
||||||
@@ -135,7 +135,7 @@ Hub::ResetPort(uint8 index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// clear the reset change
|
// 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);
|
USB_REQUEST_CLEAR_FEATURE, C_PORT_RESET, index + 1, 0, NULL, 0, NULL);
|
||||||
if (result < B_OK)
|
if (result < B_OK)
|
||||||
return result;
|
return result;
|
||||||
@@ -155,9 +155,7 @@ Hub::Explore()
|
|||||||
if (result < B_OK)
|
if (result < B_OK)
|
||||||
continue;
|
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].change & PORT_STATUS_CONNECTION) {
|
||||||
if (fPortStatus[i].status & PORT_STATUS_CONNECTION) {
|
if (fPortStatus[i].status & PORT_STATUS_CONNECTION) {
|
||||||
// new device attached!
|
// new device attached!
|
||||||
@@ -190,7 +188,7 @@ Hub::Explore()
|
|||||||
// the device failed to setup correctly, disable the port
|
// the device failed to setup correctly, disable the port
|
||||||
// so that the device doesn't get in the way of future
|
// so that the device doesn't get in the way of future
|
||||||
// addressing.
|
// 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,
|
USB_REQUEST_CLEAR_FEATURE, PORT_ENABLE, i + 1,
|
||||||
0, NULL, 0, NULL);
|
0, NULL, 0, NULL);
|
||||||
}
|
}
|
||||||
@@ -199,14 +197,13 @@ Hub::Explore()
|
|||||||
TRACE(("USB Hub Explore(): Device removed\n"));
|
TRACE(("USB Hub Explore(): Device removed\n"));
|
||||||
if (fChildren[i]) {
|
if (fChildren[i]) {
|
||||||
GetStack()->NotifyDeviceChange(fChildren[i], false);
|
GetStack()->NotifyDeviceChange(fChildren[i], false);
|
||||||
GetStack()->PutUSBID(fChildren[i]->USBID());
|
|
||||||
delete fChildren[i];
|
delete fChildren[i];
|
||||||
fChildren[i] = NULL;
|
fChildren[i] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear status change
|
// 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,
|
USB_REQUEST_CLEAR_FEATURE, C_PORT_CONNECTION, i + 1,
|
||||||
0, NULL, 0, NULL);
|
0, NULL, 0, NULL);
|
||||||
}
|
}
|
||||||
@@ -234,7 +231,7 @@ status_t
|
|||||||
Hub::GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID,
|
Hub::GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID,
|
||||||
void *data, size_t dataLength, size_t *actualLength)
|
void *data, size_t dataLength, size_t *actualLength)
|
||||||
{
|
{
|
||||||
return SendRequest(
|
return DefaultPipe()->SendRequest(
|
||||||
USB_REQTYPE_DEVICE_IN | USB_REQTYPE_CLASS, // type
|
USB_REQTYPE_DEVICE_IN | USB_REQTYPE_CLASS, // type
|
||||||
USB_REQUEST_GET_DESCRIPTOR, // request
|
USB_REQUEST_GET_DESCRIPTOR, // request
|
||||||
(descriptorType << 8) | index, // value
|
(descriptorType << 8) | index, // value
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
#include "usb_p.h"
|
#include "usb_p.h"
|
||||||
|
|
||||||
|
|
||||||
Interface::Interface(BusManager *bus, int8 deviceAddress, pipeSpeed speed)
|
Interface::Interface(Object *parent)
|
||||||
: ControlPipe(bus, deviceAddress, speed, 0, 8)
|
: Object(parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ Interface::Interface(BusManager *bus, int8 deviceAddress, pipeSpeed speed)
|
|||||||
status_t
|
status_t
|
||||||
Interface::SetFeature(uint16 selector)
|
Interface::SetFeature(uint16 selector)
|
||||||
{
|
{
|
||||||
return SendRequest(
|
return ((Device *)Parent())->DefaultPipe()->SendRequest(
|
||||||
USB_REQTYPE_STANDARD | USB_REQTYPE_INTERFACE_OUT,
|
USB_REQTYPE_STANDARD | USB_REQTYPE_INTERFACE_OUT,
|
||||||
USB_REQUEST_SET_FEATURE,
|
USB_REQUEST_SET_FEATURE,
|
||||||
selector,
|
selector,
|
||||||
@@ -33,7 +33,7 @@ Interface::SetFeature(uint16 selector)
|
|||||||
status_t
|
status_t
|
||||||
Interface::ClearFeature(uint16 selector)
|
Interface::ClearFeature(uint16 selector)
|
||||||
{
|
{
|
||||||
return SendRequest(
|
return ((Device *)Parent())->DefaultPipe()->SendRequest(
|
||||||
USB_REQTYPE_STANDARD | USB_REQTYPE_INTERFACE_OUT,
|
USB_REQTYPE_STANDARD | USB_REQTYPE_INTERFACE_OUT,
|
||||||
USB_REQUEST_CLEAR_FEATURE,
|
USB_REQUEST_CLEAR_FEATURE,
|
||||||
selector,
|
selector,
|
||||||
@@ -48,7 +48,7 @@ Interface::ClearFeature(uint16 selector)
|
|||||||
status_t
|
status_t
|
||||||
Interface::GetStatus(uint16 *status)
|
Interface::GetStatus(uint16 *status)
|
||||||
{
|
{
|
||||||
return SendRequest(
|
return ((Device *)Parent())->DefaultPipe()->SendRequest(
|
||||||
USB_REQTYPE_STANDARD | USB_REQTYPE_INTERFACE_IN,
|
USB_REQTYPE_STANDARD | USB_REQTYPE_INTERFACE_IN,
|
||||||
USB_REQUEST_GET_STATUS,
|
USB_REQUEST_GET_STATUS,
|
||||||
0,
|
0,
|
||||||
|
|||||||
@@ -9,9 +9,52 @@
|
|||||||
#include "usb_p.h"
|
#include "usb_p.h"
|
||||||
|
|
||||||
|
|
||||||
Object::Object(BusManager *bus)
|
Object::Object(Stack *stack, BusManager *bus)
|
||||||
: fBusManager(bus),
|
: fParent(NULL),
|
||||||
fStack(bus->GetStack()),
|
fBusManager(bus),
|
||||||
|
fStack(stack),
|
||||||
fUSBID(fStack->GetUSBID(this))
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,9 +10,9 @@
|
|||||||
#include "usb_p.h"
|
#include "usb_p.h"
|
||||||
|
|
||||||
|
|
||||||
Pipe::Pipe(BusManager *bus, int8 deviceAddress, pipeDirection direction,
|
Pipe::Pipe(Object *parent, int8 deviceAddress, uint8 endpointAddress,
|
||||||
pipeSpeed speed, uint8 endpointAddress, size_t maxPacketSize)
|
pipeDirection direction, pipeSpeed speed, size_t maxPacketSize)
|
||||||
: Object(bus),
|
: Object(parent),
|
||||||
fDeviceAddress(deviceAddress),
|
fDeviceAddress(deviceAddress),
|
||||||
fEndpointAddress(endpointAddress),
|
fEndpointAddress(endpointAddress),
|
||||||
fDirection(direction),
|
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 -
|
// #pragma mark -
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
InterruptPipe::InterruptPipe(BusManager *bus, int8 deviceAddress,
|
InterruptPipe::InterruptPipe(Object *parent, int8 deviceAddress,
|
||||||
pipeDirection direction, pipeSpeed speed, uint8 endpointAddress,
|
uint8 endpointAddress, pipeDirection direction, pipeSpeed speed,
|
||||||
size_t maxPacketSize)
|
size_t maxPacketSize)
|
||||||
: Pipe(bus, deviceAddress, direction, speed, endpointAddress,
|
: Pipe(parent, deviceAddress, endpointAddress, direction, speed,
|
||||||
maxPacketSize)
|
maxPacketSize)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -80,10 +125,9 @@ InterruptPipe::QueueInterrupt(void *data, size_t dataLength,
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
BulkPipe::BulkPipe(BusManager *bus, int8 deviceAddress,
|
BulkPipe::BulkPipe(Object *parent, int8 deviceAddress, uint8 endpointAddress,
|
||||||
pipeDirection direction, pipeSpeed speed, uint8 endpointAddress,
|
pipeDirection direction, pipeSpeed speed, size_t maxPacketSize)
|
||||||
size_t maxPacketSize)
|
: Pipe(parent, deviceAddress, endpointAddress, direction, speed,
|
||||||
: Pipe(bus, deviceAddress, direction, speed, endpointAddress,
|
|
||||||
maxPacketSize)
|
maxPacketSize)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -130,10 +174,10 @@ BulkPipe::QueueBulkV(iovec *vector, size_t vectorCount,
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
IsochronousPipe::IsochronousPipe(BusManager *bus, int8 deviceAddress,
|
IsochronousPipe::IsochronousPipe(Object *parent, int8 deviceAddress,
|
||||||
pipeDirection direction, pipeSpeed speed, uint8 endpointAddress,
|
uint8 endpointAddress, pipeDirection direction, pipeSpeed speed,
|
||||||
size_t maxPacketSize)
|
size_t maxPacketSize)
|
||||||
: Pipe(bus, deviceAddress, direction, speed, endpointAddress,
|
: Pipe(parent, deviceAddress, endpointAddress, direction, speed,
|
||||||
maxPacketSize)
|
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;
|
sem_id notify_sem;
|
||||||
uint32 status;
|
uint32 status;
|
||||||
size_t actual_length;
|
size_t actual_length;
|
||||||
};
|
} transfer_result_data;
|
||||||
|
|
||||||
|
|
||||||
ControlPipe::ControlPipe(BusManager *bus, int8 deviceAddress, pipeSpeed speed,
|
ControlPipe::ControlPipe(Object *parent, int8 deviceAddress,
|
||||||
uint8 endpointAddress, size_t maxPacketSize)
|
uint8 endpointAddress, pipeSpeed speed, size_t maxPacketSize)
|
||||||
: Pipe(bus, deviceAddress, Default, speed, endpointAddress, maxPacketSize)
|
: Pipe(parent, deviceAddress, endpointAddress, Default, speed,
|
||||||
|
maxPacketSize)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,48 +286,3 @@ ControlPipe::QueueRequest(uint8 requestType, uint8 request, uint16 value,
|
|||||||
delete transfer;
|
delete transfer;
|
||||||
return result;
|
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);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
* Niels S. Reedijk
|
* Niels S. Reedijk
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define TRACE_USB
|
||||||
#include <util/kernel_cpp.h>
|
#include <util/kernel_cpp.h>
|
||||||
#include "usb_p.h"
|
#include "usb_p.h"
|
||||||
#include <USB_rle.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));
|
TRACE(("usb_module: set_feature(0x%08x, %d)\n", handle, selector));
|
||||||
Object *object = gUSBStack->GetObject(handle);
|
Object *object = gUSBStack->GetObject(handle);
|
||||||
if (!object || (object->Type() & USB_OBJECT_CONTROL_PIPE) == 0)
|
if (!object)
|
||||||
return B_BAD_VALUE;
|
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));
|
TRACE(("usb_module: clear_feature(0x%08x, %d)\n", handle, selector));
|
||||||
Object *object = gUSBStack->GetObject(handle);
|
Object *object = gUSBStack->GetObject(handle);
|
||||||
if (!object || (object->Type() & USB_OBJECT_CONTROL_PIPE) == 0)
|
if (!object)
|
||||||
return B_BAD_VALUE;
|
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;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
Object *object = gUSBStack->GetObject(handle);
|
Object *object = gUSBStack->GetObject(handle);
|
||||||
if (!object || (object->Type() & USB_OBJECT_CONTROL_PIPE) == 0)
|
if (!object)
|
||||||
return B_BAD_VALUE;
|
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)
|
if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
return ((Device *)object)->SendRequest(requestType, request, value, index,
|
return ((Device *)object)->DefaultPipe()->SendRequest(requestType, request,
|
||||||
length, data, length, actualLength);
|
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)
|
if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
return ((Device *)object)->QueueRequest(requestType, request, value, index,
|
return ((Device *)object)->DefaultPipe()->QueueRequest(requestType,
|
||||||
length, data, length, callback, callbackCookie);
|
request, value, index, length, data, length, callback, callbackCookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -138,18 +138,16 @@ virtual status_t InitCheck();
|
|||||||
bool Lock();
|
bool Lock();
|
||||||
void Unlock();
|
void Unlock();
|
||||||
|
|
||||||
Device *AllocateNewDevice(Device *parent,
|
|
||||||
bool lowSpeed);
|
|
||||||
|
|
||||||
int8 AllocateAddress();
|
int8 AllocateAddress();
|
||||||
|
Device *AllocateNewDevice(Hub *parent,
|
||||||
|
bool lowSpeed);
|
||||||
|
|
||||||
virtual status_t Start();
|
virtual status_t Start();
|
||||||
virtual status_t Stop();
|
virtual status_t Stop();
|
||||||
|
|
||||||
virtual status_t SubmitTransfer(Transfer *transfer);
|
virtual status_t SubmitTransfer(Transfer *transfer);
|
||||||
|
|
||||||
Stack *GetStack() { return fStack; };
|
Object *RootObject() { return fRootObject; };
|
||||||
void SetStack(Stack *stack) { fStack = stack; };
|
|
||||||
|
|
||||||
Hub *GetRootHub() { return fRootHub; };
|
Hub *GetRootHub() { return fRootHub; };
|
||||||
void SetRootHub(Hub *hub) { fRootHub = hub; };
|
void SetRootHub(Hub *hub) { fRootHub = hub; };
|
||||||
@@ -165,14 +163,18 @@ static int32 ExploreThread(void *data);
|
|||||||
ControlPipe *fDefaultPipe;
|
ControlPipe *fDefaultPipe;
|
||||||
ControlPipe *fDefaultPipeLowSpeed;
|
ControlPipe *fDefaultPipeLowSpeed;
|
||||||
Hub *fRootHub;
|
Hub *fRootHub;
|
||||||
Stack *fStack;
|
|
||||||
thread_id fExploreThread;
|
thread_id fExploreThread;
|
||||||
|
Object *fRootObject;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Object {
|
class Object {
|
||||||
public:
|
public:
|
||||||
Object(BusManager *bus);
|
Object(Stack *stack, BusManager *bus);
|
||||||
|
Object(Object *parent);
|
||||||
|
virtual ~Object();
|
||||||
|
|
||||||
|
Object *Parent() { return fParent; };
|
||||||
|
|
||||||
BusManager *GetBusManager() { return fBusManager; };
|
BusManager *GetBusManager() { return fBusManager; };
|
||||||
Stack *GetStack() { return fStack; };
|
Stack *GetStack() { return fStack; };
|
||||||
@@ -180,7 +182,13 @@ public:
|
|||||||
usb_id USBID() { return fUSBID; };
|
usb_id USBID() { return fUSBID; };
|
||||||
virtual uint32 Type() { return USB_OBJECT_NONE; };
|
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:
|
private:
|
||||||
|
Object *fParent;
|
||||||
BusManager *fBusManager;
|
BusManager *fBusManager;
|
||||||
Stack *fStack;
|
Stack *fStack;
|
||||||
usb_id fUSBID;
|
usb_id fUSBID;
|
||||||
@@ -196,11 +204,11 @@ public:
|
|||||||
enum pipeDirection { In, Out, Default };
|
enum pipeDirection { In, Out, Default };
|
||||||
enum pipeSpeed { LowSpeed, FullSpeed, HighSpeed };
|
enum pipeSpeed { LowSpeed, FullSpeed, HighSpeed };
|
||||||
|
|
||||||
Pipe(BusManager *bus,
|
Pipe(Object *parent,
|
||||||
int8 deviceAddress,
|
int8 deviceAddress,
|
||||||
|
uint8 endpointAddress,
|
||||||
pipeDirection direction,
|
pipeDirection direction,
|
||||||
pipeSpeed speed,
|
pipeSpeed speed,
|
||||||
uint8 endpointAddress,
|
|
||||||
size_t maxPacketSize);
|
size_t maxPacketSize);
|
||||||
virtual ~Pipe();
|
virtual ~Pipe();
|
||||||
|
|
||||||
@@ -218,7 +226,12 @@ virtual void SetDataToggle(bool toggle) { fDataToggle = toggle; };
|
|||||||
status_t SubmitTransfer(Transfer *transfer);
|
status_t SubmitTransfer(Transfer *transfer);
|
||||||
status_t CancelQueuedTransfers();
|
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;
|
int8 fDeviceAddress;
|
||||||
uint8 fEndpointAddress;
|
uint8 fEndpointAddress;
|
||||||
pipeDirection fDirection;
|
pipeDirection fDirection;
|
||||||
@@ -230,10 +243,10 @@ protected:
|
|||||||
|
|
||||||
class ControlPipe : public Pipe {
|
class ControlPipe : public Pipe {
|
||||||
public:
|
public:
|
||||||
ControlPipe(BusManager *bus,
|
ControlPipe(Object *parent,
|
||||||
int8 deviceAddress,
|
int8 deviceAddress,
|
||||||
pipeSpeed speed,
|
|
||||||
uint8 endpointAddress,
|
uint8 endpointAddress,
|
||||||
|
pipeSpeed speed,
|
||||||
size_t maxPacketSize);
|
size_t maxPacketSize);
|
||||||
|
|
||||||
virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE; };
|
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,
|
void *data, size_t dataLength,
|
||||||
usb_callback_func callback,
|
usb_callback_func callback,
|
||||||
void *callbackCookie);
|
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 {
|
class InterruptPipe : public Pipe {
|
||||||
public:
|
public:
|
||||||
InterruptPipe(BusManager *bus,
|
InterruptPipe(Object *parent,
|
||||||
int8 deviceAddress,
|
int8 deviceAddress,
|
||||||
|
uint8 endpointAddress,
|
||||||
pipeDirection direction,
|
pipeDirection direction,
|
||||||
pipeSpeed speed,
|
pipeSpeed speed,
|
||||||
uint8 endpointAddress,
|
|
||||||
size_t maxPacketSize);
|
size_t maxPacketSize);
|
||||||
|
|
||||||
virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_INTERRUPT_PIPE; };
|
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 {
|
class BulkPipe : public Pipe {
|
||||||
public:
|
public:
|
||||||
BulkPipe(BusManager *bus,
|
BulkPipe(Object *parent,
|
||||||
int8 deviceAddress,
|
int8 deviceAddress,
|
||||||
|
uint8 endpointAddress,
|
||||||
pipeDirection direction,
|
pipeDirection direction,
|
||||||
pipeSpeed speed,
|
pipeSpeed speed,
|
||||||
uint8 endpointAddress,
|
|
||||||
size_t maxPacketSize);
|
size_t maxPacketSize);
|
||||||
|
|
||||||
virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_BULK_PIPE; };
|
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 {
|
class IsochronousPipe : public Pipe {
|
||||||
public:
|
public:
|
||||||
IsochronousPipe(BusManager *bus,
|
IsochronousPipe(Object *parent,
|
||||||
int8 deviceAddress,
|
int8 deviceAddress,
|
||||||
|
uint8 endpointAddress,
|
||||||
pipeDirection direction,
|
pipeDirection direction,
|
||||||
pipeSpeed speed,
|
pipeSpeed speed,
|
||||||
uint8 endpointAddress,
|
|
||||||
size_t maxPacketSize);
|
size_t maxPacketSize);
|
||||||
|
|
||||||
virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_ISO_PIPE; };
|
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:
|
public:
|
||||||
Interface(BusManager *bus,
|
Interface(Object *parent);
|
||||||
int8 deviceAddress,
|
|
||||||
pipeSpeed speed);
|
|
||||||
|
|
||||||
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
|
// Convenience functions for standard requests
|
||||||
virtual status_t SetFeature(uint16 selector);
|
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:
|
public:
|
||||||
Device(BusManager *bus, Device *parent,
|
Device(Object *parent,
|
||||||
usb_device_descriptor &desc,
|
usb_device_descriptor &desc,
|
||||||
int8 deviceAddress, bool lowSpeed);
|
int8 deviceAddress, bool lowSpeed);
|
||||||
|
|
||||||
status_t InitCheck();
|
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,
|
virtual status_t GetDescriptor(uint8 descriptorType,
|
||||||
uint8 index, uint16 languageID,
|
uint8 index, uint16 languageID,
|
||||||
@@ -384,26 +392,28 @@ virtual status_t GetStatus(uint16 *status);
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
usb_device_descriptor fDeviceDescriptor;
|
usb_device_descriptor fDeviceDescriptor;
|
||||||
|
bool fInitOK;
|
||||||
|
|
||||||
|
private:
|
||||||
usb_configuration_info *fConfigurations;
|
usb_configuration_info *fConfigurations;
|
||||||
usb_configuration_info *fCurrentConfiguration;
|
usb_configuration_info *fCurrentConfiguration;
|
||||||
bool fInitOK;
|
|
||||||
bool fLowSpeed;
|
bool fLowSpeed;
|
||||||
Device *fParent;
|
|
||||||
int8 fDeviceAddress;
|
int8 fDeviceAddress;
|
||||||
size_t fMaxPacketIn[16];
|
size_t fMaxPacketIn[16];
|
||||||
size_t fMaxPacketOut[16];
|
size_t fMaxPacketOut[16];
|
||||||
sem_id fLock;
|
sem_id fLock;
|
||||||
void *fNotifyCookie;
|
void *fNotifyCookie;
|
||||||
|
ControlPipe *fDefaultPipe;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Hub : public Device {
|
class Hub : public Device {
|
||||||
public:
|
public:
|
||||||
Hub(BusManager *bus, Device *parent,
|
Hub(Object *parent,
|
||||||
usb_device_descriptor &desc,
|
usb_device_descriptor &desc,
|
||||||
int8 deviceAddress, bool lowSpeed);
|
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,
|
virtual status_t GetDescriptor(uint8 descriptorType,
|
||||||
uint8 index, uint16 languageID,
|
uint8 index, uint16 languageID,
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ EHCI::Start()
|
|||||||
}
|
}
|
||||||
|
|
||||||
fRootHubAddress = AllocateAddress();
|
fRootHubAddress = AllocateAddress();
|
||||||
fRootHub = new(std::nothrow) EHCIRootHub(this, fRootHubAddress);
|
fRootHub = new(std::nothrow) EHCIRootHub(RootObject(), fRootHubAddress);
|
||||||
if (!fRootHub) {
|
if (!fRootHub) {
|
||||||
TRACE_ERROR(("usb_ehci: no memory to allocate root hub\n"));
|
TRACE_ERROR(("usb_ehci: no memory to allocate root hub\n"));
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|||||||
@@ -134,7 +134,8 @@ static pci_module_info *sPCIModule;
|
|||||||
|
|
||||||
class EHCIRootHub : public Hub {
|
class EHCIRootHub : public Hub {
|
||||||
public:
|
public:
|
||||||
EHCIRootHub(EHCI *ehci, int8 deviceAddress);
|
EHCIRootHub(Object *rootObject,
|
||||||
|
int8 deviceAddress);
|
||||||
|
|
||||||
static status_t ProcessTransfer(EHCI *ehci,
|
static status_t ProcessTransfer(EHCI *ehci,
|
||||||
Transfer *transfer);
|
Transfer *transfer);
|
||||||
|
|||||||
@@ -95,27 +95,34 @@ static ehci_root_hub_string_s sEHCIRootHubStrings[3] = {
|
|||||||
{
|
{
|
||||||
4, // Descriptor length
|
4, // Descriptor length
|
||||||
USB_DESCRIPTOR_STRING, // Descriptor type
|
USB_DESCRIPTOR_STRING, // Descriptor type
|
||||||
0x0409 // Supported language IDs (English US)
|
{
|
||||||
|
0x0409 // Supported language IDs (English US)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
12, // Descriptor length
|
12, // Descriptor length
|
||||||
USB_DESCRIPTOR_STRING, // Descriptor type
|
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
|
26, // Descriptor length
|
||||||
USB_DESCRIPTOR_STRING, // Descriptor type
|
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)
|
EHCIRootHub::EHCIRootHub(Object *rootObject, int8 deviceAddress)
|
||||||
: Hub(ehci, NULL, sEHCIRootHubDevice, deviceAddress, false)
|
: Hub(rootObject, sEHCIRootHubDevice, deviceAddress, false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ usb_hub_descriptor ohci_hubd =
|
|||||||
|
|
||||||
//Implementation
|
//Implementation
|
||||||
OHCIRootHub::OHCIRootHub( OHCI *ohci , int8 devicenum )
|
OHCIRootHub::OHCIRootHub( OHCI *ohci , int8 devicenum )
|
||||||
: Hub( ohci , NULL , ohci_devd , devicenum , false )
|
: Hub( ohci->RootObject() , ohci_devd , devicenum , false )
|
||||||
{
|
{
|
||||||
m_ohci = ohci;
|
m_ohci = ohci;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -483,7 +483,7 @@ UHCI::Start()
|
|||||||
}
|
}
|
||||||
|
|
||||||
fRootHubAddress = AllocateAddress();
|
fRootHubAddress = AllocateAddress();
|
||||||
fRootHub = new(std::nothrow) UHCIRootHub(this, fRootHubAddress);
|
fRootHub = new(std::nothrow) UHCIRootHub(RootObject(), fRootHubAddress);
|
||||||
if (!fRootHub) {
|
if (!fRootHub) {
|
||||||
TRACE_ERROR(("usb_uhci: no memory to allocate root hub\n"));
|
TRACE_ERROR(("usb_uhci: no memory to allocate root hub\n"));
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|||||||
@@ -161,7 +161,8 @@ static pci_module_info *sPCIModule;
|
|||||||
|
|
||||||
class UHCIRootHub : public Hub {
|
class UHCIRootHub : public Hub {
|
||||||
public:
|
public:
|
||||||
UHCIRootHub(UHCI *uhci, int8 deviceAddress);
|
UHCIRootHub(Object *rootObject,
|
||||||
|
int8 deviceAddress);
|
||||||
|
|
||||||
static status_t ProcessTransfer(UHCI *uhci,
|
static status_t ProcessTransfer(UHCI *uhci,
|
||||||
Transfer *transfer);
|
Transfer *transfer);
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ static uhci_root_hub_string_s sUHCIRootHubStrings[3] = {
|
|||||||
4, // Descriptor length
|
4, // Descriptor length
|
||||||
USB_DESCRIPTOR_STRING, // Descriptor type
|
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
|
12, // Descriptor length
|
||||||
USB_DESCRIPTOR_STRING, // Descriptor type
|
USB_DESCRIPTOR_STRING, // Descriptor type
|
||||||
{
|
{
|
||||||
'H', 'A', 'I', 'K', 'U', ' ', // Characters
|
'H', 'A', 'I', 'K', 'U', // Characters
|
||||||
'I', 'n', 'c', '.'
|
' ', 'I', 'n', 'c', '.'
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
@@ -117,15 +117,16 @@ static uhci_root_hub_string_s sUHCIRootHubStrings[3] = {
|
|||||||
26, // Descriptor length
|
26, // Descriptor length
|
||||||
USB_DESCRIPTOR_STRING, // Descriptor type
|
USB_DESCRIPTOR_STRING, // Descriptor type
|
||||||
{
|
{
|
||||||
'U', 'H', 'C', 'I', ' ', 'R', // Characters
|
'U', 'H', 'C', 'I', ' ', // Characters
|
||||||
'o', 'o', 't', 'H', 'u', 'b'
|
'R', 'o', 'o', 't', 'H',
|
||||||
|
'u', 'b'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
UHCIRootHub::UHCIRootHub(UHCI *uhci, int8 deviceAddress)
|
UHCIRootHub::UHCIRootHub(Object *rootObject, int8 deviceAddress)
|
||||||
: Hub(uhci, NULL, sUHCIRootHubDevice, deviceAddress, false)
|
: Hub(rootObject, sUHCIRootHubDevice, deviceAddress, false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user