Applying style to remaining classes. No functional change.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17624 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2006-05-28 23:29:06 +00:00
parent 64312bc94c
commit 96da8285b0
11 changed files with 801 additions and 810 deletions

View File

@ -70,6 +70,7 @@ BusManager::ExploreThread(void *data)
return B_ERROR; return B_ERROR;
while (true) { while (true) {
//snooze(5000000);
rootHub->Explore(); rootHub->Explore();
snooze(1000000); snooze(1000000);
} }

View File

@ -1,129 +1,138 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2003-2004, Niels S. Reedijk * Copyright 2003-2006, Haiku Inc. All rights reserved.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * Niels S. Reedijk
// the rights to use, copy, modify, merge, publish, distribute, sublicense, */
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#include "usb_p.h" #include "usb_p.h"
Device::Device( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum , bool lowspeed )
#define TRACE_USB_DEVICE
#ifdef TRACE_USB_DEVICE
#define TRACE(x) dprintf x
#else
#define TRACE(x) /* nothing */
#endif
Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc,
int8 deviceAddress, bool lowSpeed)
{ {
status_t retval; fBus = bus;
fParent = parent;
m_bus = bus; fInitOK = false;
m_parent = parent; fCurrentConfiguration = NULL;
m_initok = false; fDeviceAddress = deviceAddress;
m_configurations = 0;
m_current_configuration = 0; TRACE(("USB Device: new device\n"));
dprintf( "USB Device: new device\n" ); fLock = create_sem(1, "USB Device Lock");
if (fLock < B_OK) {
//1. Create the semaphore TRACE(("USB Device: could not create semaphore\n"));
m_lock = create_sem( 1 , "device_sem" );
if ( m_lock < B_OK )
{
dprintf( "usb Device: could not create semaphore\n" );
return; return;
} }
set_sem_owner( m_lock , B_SYSTEM_TEAM );
set_sem_owner(fLock, B_SYSTEM_TEAM);
//2. Set the free entry free entry in the device map (for the device number)
m_devicenum = devicenum; fLowSpeed = lowSpeed;
fDeviceDescriptor = desc;
//3. Set up the pipe stuff fMaxPacketIn[0] = fMaxPacketOut[0] = fDeviceDescriptor.max_packet_size_0;
//Set the maximum transfer numbers for the incoming and the outgoing packets on endpoint 0 fDefaultPipe = new ControlPipe(this, Pipe::Default,
m_maxpacketin[0] = m_maxpacketout[0] = m_device_descriptor.max_packet_size_0; lowSpeed ? Pipe::LowSpeed : Pipe::NormalSpeed, 0);
m_device_descriptor = desc;
m_lowspeed = lowspeed; // Get the device descriptor
m_defaultPipe = new ControlPipe( this , Pipe::Default , 0 );
//4. Get the device descriptor
// We already have a part of it, but we want it all // We already have a part of it, but we want it all
retval = GetDescriptor( USB_DESCRIPTOR_DEVICE , 0 , status_t status = GetDescriptor(USB_DESCRIPTOR_DEVICE, 0,
(void *)&m_device_descriptor , sizeof(m_device_descriptor ) ); (void *)&fDeviceDescriptor, sizeof(fDeviceDescriptor));
if ( retval != sizeof( m_device_descriptor ) ) if (status != sizeof(fDeviceDescriptor)) {
{ TRACE(("USB Device: error while getting the device descriptor\n"));
dprintf( "usb Device: error while getting the device descriptor\n" );
return; return;
} }
dprintf( "usb Device %d: Vendor id: %d , Product id: %d\n" , devicenum , TRACE(("USB Device %d: Vendor id: 0x%04x, Product id: 0x%04x, Device version: 0x%04x\n",
m_device_descriptor.vendor_id , m_device_descriptor.product_id ); fDeviceAddress, fDeviceDescriptor.vendor_id,
fDeviceDescriptor.product_id, fDeviceDescriptor.device_version));
// 4. Get the configurations
m_configurations = (usb_configuration_descriptor *)malloc( m_device_descriptor.num_configurations * sizeof (usb_configuration_descriptor) ); // Get the configurations
if ( m_configurations == 0 ) fConfigurations = (usb_configuration_descriptor *)malloc(fDeviceDescriptor.num_configurations
{ * sizeof(usb_configuration_descriptor));
dprintf( "usb Device: out of memory during config creations!\n" ); if (fConfigurations == NULL) {
TRACE(("USB Device: out of memory during config creations!\n"));
return; return;
} }
for ( int i = 0 ; i < m_device_descriptor.num_configurations ; i++ ) for (int32 i = 0; i < fDeviceDescriptor.num_configurations; i++) {
{ size_t size = GetDescriptor(USB_DESCRIPTOR_CONFIGURATION, i,
if ( GetDescriptor( USB_DESCRIPTOR_CONFIGURATION , i , (void *)&fConfigurations[i], sizeof(usb_configuration_descriptor));
(void *)( m_configurations + i ) , sizeof (usb_configuration_descriptor ) ) != sizeof( usb_configuration_descriptor ) )
{ if (size != sizeof(usb_configuration_descriptor)) {
dprintf( "usb Device %d: error fetching configuration %d ...\n" , m_devicenum , i ); TRACE(("USB Device %d: error fetching configuration %d\n", fDeviceAddress, i));
return; return;
} }
} }
// 5. Set the default configuration // Set default configuration
dprintf( "usb Device %d: setting configuration %d\n" , m_devicenum , 0 ); TRACE(("USB Device %d: setting default configuration\n", fDeviceAddress));
SetConfiguration( 0 ); SetConfiguration(0);
//6. TODO: Find drivers for the device // ToDo: Find drivers for the device
fInitOK = true;
m_initok = true;
} }
//Returns the length that was copied (index gives the number of the config)
int16 Device::GetDescriptor( uint8 descriptor_type , uint16 index ,
void *buffer , size_t size )
{
size_t actual_length = 0;
m_defaultPipe->SendRequest(USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD , //Type
USB_REQUEST_GET_DESCRIPTOR , //Request
( descriptor_type << 8 ) | index , //Value
0 , //Index
size , //Length
buffer , //Buffer
size , //Bufferlength
&actual_length ); //length
return actual_length;
}
status_t Device::SetConfiguration( uint8 value )
{
if ( value >= m_device_descriptor.num_configurations )
return EINVAL;
m_defaultPipe->SendRequest( USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD , //Type
USB_REQUEST_SET_CONFIGURATION , //Request
value , //Value
0 , //Index
0 , //Length
NULL , //Buffer
0 , //Bufferlength
0 ); //length
//Set current configuration status_t
m_current_configuration = m_configurations + value; Device::InitCheck()
{
if (fInitOK)
return B_OK;
return B_ERROR;
}
// Returns the length that was copied (index gives the number of the config)
size_t
Device::GetDescriptor(uint8 descriptorType, uint16 index, void *buffer,
size_t bufferSize)
{
size_t actualLength = 0;
fDefaultPipe->SendRequest(
USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD, // type
USB_REQUEST_GET_DESCRIPTOR, // request
(descriptorType << 8) | index, // value
0, // index
bufferSize, // length
buffer, // buffer
bufferSize, // buffer length
&actualLength); // actual length
return actualLength;
}
status_t
Device::SetConfiguration(uint8 value)
{
if (value >= fDeviceDescriptor.num_configurations)
return EINVAL;
status_t result = fDefaultPipe->SendRequest(
USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD, // type
USB_REQUEST_SET_CONFIGURATION, // request
value, // value
0, // index
0, // length
NULL, // buffer
0, // buffer length
NULL); // actual length
if (result < B_OK)
return result;
// Set current configuration
fCurrentConfiguration = &fConfigurations[value];
return B_OK; return B_OK;
} }

View File

@ -1,192 +1,174 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2003-2004, Niels S. Reedijk * Copyright 2003-2006, Haiku Inc. All rights reserved.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * Niels S. Reedijk
// the rights to use, copy, modify, merge, publish, distribute, sublicense, */
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#include "usb_p.h" #include "usb_p.h"
Hub::Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum , bool lowspeed )
: Device ( bus , parent , desc , devicenum , lowspeed )
{
dprintf( "USB Hub is being initialised\n" );
size_t actual_length;
if ( m_initok == false ) #define TRACE_HUB
{ #ifdef TRACE_HUB
dprintf( "Hub::Hub() Device failed to initialize\n" ); #define TRACE(x) dprintf x
#else
#define TRACE(x) /* nothing */
#endif
Hub::Hub(BusManager *bus, Device *parent, usb_device_descriptor &desc,
int8 deviceAddress, bool lowSpeed)
: Device(bus, parent, desc, deviceAddress, lowSpeed)
{
TRACE(("USB Hub is being initialised\n"));
if (!fInitOK) {
TRACE(("USB Hub: Device failed to initialize\n"));
return; return;
} }
//Set to false again for the hub init. // Set to false again for the hub init.
m_initok = false; fInitOK = false;
if( m_device_descriptor.device_subclass != 0 || m_device_descriptor.device_protocol != 0 ) if (fDeviceDescriptor.device_subclass != 0
{ || fDeviceDescriptor.device_protocol != 0) {
dprintf( "USB Hub: wrong class/subclass/protocol! Bailing out\n" ); TRACE(("USB Hub: wrong class/subclass/protocol! Bailing out\n"));
return; return;
} }
if ( m_current_configuration->number_interfaces > 1 ) if (fCurrentConfiguration->number_interfaces > 1) {
{ TRACE(("USB Hub: too many interfaces\n"));
dprintf( "USB Hub: too much interfaces! Bailing out\n" );
return; return;
} }
dprintf( "USB Hub this: %p" , this ); size_t actualLength;
if (GetDescriptor(USB_DESCRIPTOR_INTERFACE, 0, (void *)&fInterruptInterface,
if ( GetDescriptor( USB_DESCRIPTOR_INTERFACE , 0 , sizeof(usb_interface_descriptor)) != sizeof(usb_interface_descriptor)) {
(void *)&m_interrupt_interface , TRACE(("USB Hub: error getting the interrupt interface\n"));
sizeof (usb_interface_descriptor) ) != sizeof( usb_interface_descriptor ) )
{
dprintf( "USB Hub: error getting the interrupt interface! Bailing out.\n" );
return; return;
} }
if ( m_interrupt_interface.num_endpoints > 1 ) if (fInterruptInterface.num_endpoints > 1) {
{ TRACE(("USB Hub: too many endpoints\n"));
dprintf( "USB Hub: too much endpoints! Bailing out.\n" );
return; return;
} }
if ( GetDescriptor( USB_DESCRIPTOR_ENDPOINT , 0 , if (GetDescriptor(USB_DESCRIPTOR_ENDPOINT, 0, (void *)&fInterruptEndpoint,
(void *)&m_interrupt_endpoint , sizeof(usb_endpoint_descriptor)) != sizeof(usb_endpoint_descriptor)) {
sizeof (usb_endpoint_descriptor) ) != sizeof (usb_endpoint_descriptor ) ) TRACE(("USB Hub: Error getting the endpoint\n"));
{
dprintf( "USB Hub: Error getting the endpoint. Bailing out\n" );
return; return;
} }
if ( m_interrupt_endpoint.attributes != 0x03 ) //interrupt transfer if (fInterruptEndpoint.attributes != 0x03) { // interrupt transfer
{ TRACE(("USB Hub: Not an interrupt endpoint\n"));
dprintf( "USB Hub: Not an interrupt endpoint. Bailing out\n" );
return; return;
} }
dprintf( "USB Hub: Getting hub descriptor...\n" ); TRACE(("USB Hub: Getting hub descriptor...\n"));
if ( GetDescriptor( USB_DESCRIPTOR_HUB , 0 , if (GetDescriptor(USB_DESCRIPTOR_HUB, 0, (void *)&fHubDescriptor,
(void *)&m_hub_descriptor , sizeof(usb_hub_descriptor)) != sizeof(usb_hub_descriptor)) {
sizeof (usb_hub_descriptor) ) != sizeof (usb_hub_descriptor ) ) TRACE(("USB Hub: Error getting hub descriptor\n"));
{
dprintf( "USB Hub: Error getting hub descriptor\n" );
return; return;
} }
// Enable port power on all ports // Enable port power on all ports
for ( int i = 0 ; i < m_hub_descriptor.bNbrPorts ; i++ ) for (int32 i = 0; i < fHubDescriptor.bNbrPorts; i++) {
m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT , fDefaultPipe->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
USB_REQUEST_SET_FEATURE , USB_REQUEST_SET_FEATURE,
PORT_POWER , PORT_POWER,
i + 1 , //index i + 1,
0 , 0,
NULL , NULL,
0 , 0,
&actual_length ); &actualLength);
//Wait for power to stabilize }
snooze( m_hub_descriptor.bPwrOn2PwrGood * 2 );
// Wait for power to stabilize
//We're basically done now snooze(fHubDescriptor.bPwrOn2PwrGood * 2);
m_initok = true;
dprintf( "USB Hub: initialised ok\n" ); fInitOK = true;
TRACE(("USB Hub: initialised ok\n"));
} }
void Hub::Explore()
void
Hub::Explore()
{ {
size_t actual_length; for (int32 i = 0; i < fHubDescriptor.bNbrPorts; i++) {
size_t actualLength;
for ( int i = 0 ; i < m_hub_descriptor.bNbrPorts ; i++ )
{
// Get the current port status // Get the current port status
m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_IN , fDefaultPipe->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_IN,
USB_REQUEST_GET_STATUS , USB_REQUEST_GET_STATUS,
0 , //Value 0,
i + 1 , //Index i + 1,
4 , //length 4,
(void *)&m_port_status[i], (void *)&fPortStatus[i],
4 , 4,
&actual_length ); &actualLength);
if ( actual_length < 4 )
{ if (actualLength < 4) {
dprintf( "USB Hub: ERROR getting port status\n" ); TRACE(("USB Hub: error getting port status\n"));
return; return;
} }
dprintf("status: 0x%04x; change: 0x%04x\n", m_port_status[i].status, m_port_status[i].change);
//We need to test the port change against a number of things
if ( m_port_status[i].status & PORT_RESET )
{
//We didn't do this!
m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT ,
USB_REQUEST_CLEAR_FEATURE ,
PORT_RESET ,
i + 1 , //index
0 ,
NULL ,
0 ,
&actual_length );
}
if ( m_port_status[i].change & PORT_STATUS_CONNECTION )
{
if ( m_port_status[i].status & PORT_STATUS_CONNECTION )
{
//New device attached!
if ((m_port_status[i].status & PORT_STATUS_ENABLE) == 0) { //TRACE(("status: 0x%04x; change: 0x%04x\n", fPortStatus[i].status, fPortStatus[i].change));
// We need to test the port change against a number of things
if (fPortStatus[i].status & PORT_RESET) {
fDefaultPipe->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
USB_REQUEST_CLEAR_FEATURE,
PORT_RESET,
i + 1,
0,
NULL,
0,
&actualLength);
}
if (fPortStatus[i].change & PORT_STATUS_CONNECTION) {
if (fPortStatus[i].status & PORT_STATUS_CONNECTION) {
// New device attached!
if ((fPortStatus[i].status & PORT_STATUS_ENABLE) == 0) {
// enable the port if it isn't // enable the port if it isn't
m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT , fDefaultPipe->SendRequest(
USB_REQUEST_SET_FEATURE , USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
PORT_ENABLE , USB_REQUEST_SET_FEATURE,
i + 1 , //index PORT_ENABLE,
0 , i + 1,
NULL , 0,
0 , NULL,
&actual_length ); 0,
NULL);
} }
dprintf( "USB Hub Explore(): New device connected\n" ); TRACE(("USB Hub: Explore(): New device connected\n"));
Device *newdev;
if ( m_port_status[i].status & PORT_STATUS_LOW_SPEED ) Device *newDevice;
newdev = m_bus->AllocateNewDevice( this , true ); if (fPortStatus[i].status & PORT_STATUS_LOW_SPEED)
newDevice = fBus->AllocateNewDevice(this, true);
else else
newdev = m_bus->AllocateNewDevice( this , false ); newDevice = fBus->AllocateNewDevice(this, false);
if ( newdev != 0 )
m_children[i] = newdev; if (newDevice)
fChildren[i] = newDevice;
} else {
// Device removed...
// ToDo: do something
TRACE(("USB Hub Explore(): Device removed\n"));
} }
else
{ // Clear status change
//Device removed... fDefaultPipe->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
//DO something USB_REQUEST_CLEAR_FEATURE,
dprintf( "USB Hub Explore(): Device removed\n" ); C_PORT_CONNECTION,
i + 1,
} 0,
NULL,
//Clear status 0,
m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT , NULL);
USB_REQUEST_CLEAR_FEATURE , }
C_PORT_CONNECTION , }
i + 1 , //index
0 ,
NULL ,
0 ,
&actual_length );
} // PORT_STATUS_CONNECTION
}//for (...)
} }

View File

@ -17,7 +17,7 @@ Pipe::Pipe(Device *device, pipeDirection &direction, uint8 &endpointAddress)
fBus = NULL; fBus = NULL;
if (fDevice) if (fDevice)
fBus = fDevice->GetBusManager(); fBus = fDevice->Manager();
} }
@ -32,7 +32,7 @@ Pipe::DeviceAddress()
if (!fDevice) if (!fDevice)
return -1; return -1;
return fDevice->GetAddress(); return fDevice->Address();
} }
@ -42,9 +42,10 @@ Pipe::DeviceAddress()
ControlPipe::ControlPipe(Device *device, pipeDirection direction, ControlPipe::ControlPipe(Device *device, pipeDirection direction,
uint8 endpointAddress) pipeSpeed speed, uint8 endpointAddress)
: Pipe(device, direction, endpointAddress) : Pipe(device, direction, endpointAddress)
{ {
fSpeed = speed;
} }
@ -64,7 +65,7 @@ ControlPipe::DeviceAddress()
if (!fDevice) if (!fDevice)
return fDeviceAddress; return fDeviceAddress;
return fDevice->GetAddress(); return fDevice->Address();
} }

View File

@ -1,284 +1,296 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2003-2004, Niels S. Reedijk * Copyright 2003-2006, Haiku Inc. All rights reserved.
// * Distributed under the terms of the MIT License.
// AllocArea implementation (c) 2002 Marcus Overhagen <marcus@overhagen.de> *
// * Authors:
// Permission is hereby granted, free of charge, to any person obtaining a * Niels S. Reedijk
// copy of this software and associated documentation files (the "Software"), */
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#include <module.h> #include <module.h>
#include <util/kernel_cpp.h> #include <util/kernel_cpp.h>
#include "usb_p.h" #include "usb_p.h"
#define MODULE_NAME "usb stack: "
#define TRACE_STACK
#ifdef TRACE_STACK
#define TRACE(x) dprintf x
#else
#define TRACE(x) /* nothing */
#endif
Stack::Stack() Stack::Stack()
{ {
dprintf(MODULE_NAME"stack init\n"); TRACE(("usb stack: stack init\n"));
//Init the master lock
m_master = create_sem( 1 , "usb master lock" );
set_sem_owner( m_master , B_SYSTEM_TEAM );
//Create the data lock
m_datalock = create_sem( 1 , "usb data lock" );
set_sem_owner( m_datalock , B_SYSTEM_TEAM );
//Set the global "data" variable to this // Create the master lock
data = this; fMasterLock = create_sem(1, "usb master lock");
set_sem_owner(fMasterLock, B_SYSTEM_TEAM);
// Create the data lock
fDataLock = create_sem(1, "usb data lock");
set_sem_owner(fDataLock, B_SYSTEM_TEAM);
// Set the global "data" variable to this
usb_stack = this;
// Initialise the memory chunks: create 8, 16 and 32 byte-heaps
// NOTE: This is probably the most ugly code you will see in the
// whole stack. Unfortunately this is needed because of the fact
// that the compiler doesn't like us to apply pointer arithmethic
// to (void *) pointers.
//Initialise the memory chunks: create 8, 16 and 32 byte-heaps
//NOTE: This is probably the most ugly code you will see in the
//whole stack. Unfortunately this is needed because of the fact
//that the compiler doesn't like us to apply pointer arithmethic
//to (void *) pointers.
// 8-byte heap // 8-byte heap
m_areafreecount[0] = 0; fAreaFreeCount[0] = 0;
m_areas[0] = AllocateArea( &m_logical[0] , &m_physical[0] , B_PAGE_SIZE , fAreas[0] = AllocateArea(&fLogical[0], &fPhysical[0], B_PAGE_SIZE,
"8-byte chunk area" ); "8-byte chunk area");
if ( m_areas[0] < B_OK )
{ if (fAreas[0] < B_OK) {
dprintf(MODULE_NAME"8-byte chunk area failed to initialise\n" ); TRACE(("usb stack: 8-byte chunk area failed to initialise\n"));
return; return;
} }
m_8_listhead = (addr_t)m_logical[0]; fListhead8 = (addr_t)fLogical[0];
for (int32 i = 0; i < B_PAGE_SIZE / 8; i++) {
memory_chunk *chunk = (memory_chunk *)((addr_t)fLogical[0] + 8 * i);
chunk->physical = (addr_t)fPhysical[0] + 8 * i;
for ( int i = 0 ; i < B_PAGE_SIZE/8 ; i++ ) if (i < B_PAGE_SIZE / 8 - 1)
{ chunk->next_item = (addr_t)fLogical[0] + 8 * (i + 1);
memory_chunk *chunk = (memory_chunk *)((addr_t)m_logical[0] + 8 * i);
chunk->physical = (addr_t)m_physical[0] + 8 * i;
if ( i != B_PAGE_SIZE / 8 - 1 )
chunk->next_item = (addr_t)m_logical[0] + 8 * ( i + 1 );
else else
chunk->next_item = NULL; chunk->next_item = NULL;
} }
// 16-byte heap // 16-byte heap
m_areafreecount[1] = 0; fAreaFreeCount[1] = 0;
m_areas[1] = AllocateArea( &m_logical[1] , &m_physical[1] , B_PAGE_SIZE , fAreas[1] = AllocateArea(&fLogical[1], &fPhysical[1], B_PAGE_SIZE,
"16-byte chunk area" ); "16-byte chunk area");
if ( m_areas[1] < B_OK )
{ if (fAreas[1] < B_OK) {
dprintf(MODULE_NAME"16-byte chunk area failed to initialise\n" ); TRACE(("usb stack: 16-byte chunk area failed to initialise\n"));
return; return;
} }
m_16_listhead = (addr_t)m_logical[1]; fListhead16 = (addr_t)fLogical[1];
for (int32 i = 0; i < B_PAGE_SIZE / 16; i++) {
memory_chunk *chunk = (memory_chunk *)((addr_t)fLogical[1] + 16 * i);
chunk->physical = (addr_t)fPhysical[1] + 16 * i;
for ( int i = 0 ; i < B_PAGE_SIZE/16 ; i++ ) if (i < B_PAGE_SIZE / 16 - 1)
{ chunk->next_item = (addr_t)fLogical[1] + 16 * (i + 1);
memory_chunk *chunk = (memory_chunk *)((addr_t)m_logical[1] + 16 * i);
chunk->physical = (addr_t)m_physical[1] + 16 * i;
if ( i != B_PAGE_SIZE / 16 - 1 )
chunk->next_item = (addr_t)m_logical[1] + 16 * ( i + 1 );
else else
chunk->next_item = NULL; chunk->next_item = NULL;
} }
// 32-byte heap // 32-byte heap
m_areafreecount[2] = 0; fAreaFreeCount[2] = 0;
m_areas[2] = AllocateArea( &m_logical[2] , &m_physical[2] , B_PAGE_SIZE , fAreas[2] = AllocateArea(&fLogical[2], &fPhysical[2], B_PAGE_SIZE,
"32-byte chunk area" ); "32-byte chunk area");
if ( m_areas[2] < B_OK )
{ if (fAreas[2] < B_OK) {
dprintf(MODULE_NAME"32-byte chunk area failed to initialise\n" ); TRACE(("usb stack: 32-byte chunk area failed to initialise\n"));
return; return;
} }
m_32_listhead = (addr_t)m_logical[2]; fListhead32 = (addr_t)fLogical[2];
for (int32 i = 0; i < B_PAGE_SIZE / 32; i++) {
memory_chunk *chunk = (memory_chunk *)((addr_t)fLogical[2] + 32 * i);
chunk->physical = (addr_t)fPhysical[2] + 32 * i;
for ( int i = 0 ; i < B_PAGE_SIZE/32 ; i++ ) if (i < B_PAGE_SIZE / 32 - 1)
{ chunk->next_item = (addr_t)fLogical[2] + 32 * (i + 1);
memory_chunk *chunk = (memory_chunk *)((addr_t)m_logical[2] + 32 * i);
chunk->physical = (addr_t)m_physical[2] + 32 * i;
if ( i != B_PAGE_SIZE / 32 - 1 )
chunk->next_item = (addr_t)m_logical[2] + 32 * ( i + 1 );
else else
chunk->next_item = NULL; chunk->next_item = NULL;
} }
//Check for host controller modules // Check for host controller modules
void *list = open_module_list( "busses/usb" ); void *moduleList = open_module_list("busses/usb");
char modulename[B_PATH_NAME_LENGTH]; char moduleName[B_PATH_NAME_LENGTH];
size_t buffersize = sizeof(modulename); size_t bufferSize = sizeof(moduleName);
dprintf(MODULE_NAME"Looking for host controller modules\n" );
while( read_next_module_name( list , modulename , &buffersize ) == B_OK ) TRACE(("usb stack: Looking for host controller modules\n"));
{ while(read_next_module_name(moduleList, moduleName, &bufferSize) == B_OK) {
dprintf(MODULE_NAME"Found module %s\n" , modulename ); bufferSize = sizeof(moduleName);
buffersize = sizeof(modulename); TRACE(("usb stack: Found module %s\n", moduleName));
host_controller_info *module = 0;
if ( get_module( modulename , (module_info **)&module ) != B_OK ) host_controller_info *module = NULL;
if (get_module(moduleName, (module_info **)&module) != B_OK)
continue; continue;
if ( module->add_to( *this) != B_OK )
if (module->add_to(*this) != B_OK)
continue; continue;
dprintf(MODULE_NAME"module %s successfully loaded\n" , modulename );
TRACE(("usb stack: module %s successfully loaded\n", moduleName));
} }
if( m_busmodules.Count() == 0 ) if (fBusManagers.Count() == 0)
return; return;
} }
Stack::~Stack() Stack::~Stack()
{ {
//Release the bus modules //Release the bus modules
for( Vector<BusManager *>::Iterator i = m_busmodules.Begin() ; i != m_busmodules.End() ; i++ ) for (Vector<BusManager *>::Iterator i = fBusManagers.Begin();
i != fBusManagers.End(); i++) {
delete (*i); delete (*i);
delete_area( m_areas[0] ); }
delete_area( m_areas[1] );
delete_area( m_areas[2] );
}
status_t Stack::InitCheck() delete_area(fAreas[0]);
delete_area(fAreas[1]);
delete_area(fAreas[2]);
}
status_t
Stack::InitCheck()
{ {
if ( m_busmodules.Count() == 0 ) if (fBusManagers.Count() == 0)
return ENODEV; return ENODEV;
return B_OK; return B_OK;
} }
void Stack::Lock()
{
acquire_sem( m_master );
}
void Stack::Unlock() void
Stack::Lock()
{ {
release_sem( m_master ); acquire_sem(fMasterLock);
}
void Stack::AddBusManager( BusManager *bus )
{
m_busmodules.PushBack( bus );
} }
status_t Stack::AllocateChunk( void **log , void **phy , uint8 size ) void
Stack::Unlock()
{
release_sem(fMasterLock);
}
void
Stack::AddBusManager(BusManager *busManager)
{
fBusManagers.PushBack(busManager);
}
status_t
Stack::AllocateChunk(void **logicalAddress, void **physicalAddress, uint8 size)
{ {
Lock(); Lock();
addr_t listhead; addr_t listhead;
if ( size <= 8 ) if (size <= 8)
listhead = m_8_listhead; listhead = fListhead8;
else if ( size <= 16 ) else if (size <= 16)
listhead = m_16_listhead; listhead = fListhead16;
else if ( size <= 32 ) else if (size <= 32)
listhead = m_32_listhead; listhead = fListhead32;
else else {
{ TRACE(("usb stack: Chunk size %d to big\n", size));
dprintf (MODULE_NAME"Chunk size %i to big\n" , size );
Unlock(); Unlock();
return B_ERROR; return B_ERROR;
} }
if ( listhead == NULL ) if (listhead == NULL) {
{ TRACE(("usb stack: Out of memory on this list\n"));
Unlock(); Unlock();
dprintf(MODULE_NAME"Out of memory on this list\n" );
return B_ERROR; return B_ERROR;
} }
dprintf(MODULE_NAME"Stack::Allocate() listhead: %ld\n" , listhead ); //TRACE(("usb stack: Stack::Allocate() listhead: 0x%08x\n", listhead));
memory_chunk *chunk = (memory_chunk *)listhead; memory_chunk *chunk = (memory_chunk *)listhead;
*log = (void *)listhead; *logicalAddress = (void *)listhead;
*phy = (void *)(chunk->physical); *physicalAddress = (void *)chunk->physical;
if ( chunk->next_item == NULL ) if (chunk->next_item == NULL) {
//TODO: allocate more memory //TODO: allocate more memory
listhead = NULL; listhead = NULL;
else } else {
listhead = chunk->next_item; listhead = chunk->next_item;
}
//Update our listhead pointers
if ( size <= 8 ) // Update our listhead pointers
m_8_listhead = listhead; if (size <= 8)
else if ( size <= 16 ) fListhead8 = listhead;
m_16_listhead = listhead; else if (size <= 16)
else if ( size <= 32 ) fListhead16 = listhead;
m_32_listhead = listhead; else if (size <= 32)
fListhead32 = listhead;
Unlock(); Unlock();
dprintf(MODULE_NAME"allocated a new chunk with size %u\n" , size ); //TRACE(("usb stack: allocated a new chunk with size %u\n", size));
return B_OK; return B_OK;
} }
status_t Stack::FreeChunk( void *log , void *phy , uint8 size )
status_t
Stack::FreeChunk(void *logicalAddress, void *physicalAddress, uint8 size)
{ {
Lock(); Lock();
addr_t listhead; addr_t listhead;
if ( size <= 8 ) if (size <= 8)
listhead = m_8_listhead; listhead = fListhead8;
else if ( size <= 16 ) else if (size <= 16)
listhead = m_16_listhead; listhead = fListhead16;
else if ( size <= 32 ) else if (size <= 32)
listhead = m_32_listhead; listhead = fListhead32;
else else {
{ TRACE(("usb stack: Chunk size %d invalid\n", size));
dprintf (MODULE_NAME"Chunk size %i invalid\n" , size );
Unlock(); Unlock();
return B_ERROR; return B_ERROR;
} }
memory_chunk *chunk = (memory_chunk *)log; memory_chunk *chunk = (memory_chunk *)logicalAddress;
chunk->next_item = listhead; chunk->next_item = listhead;
chunk->physical = (addr_t)phy; chunk->physical = (addr_t)physicalAddress;
if ( size <= 8 ) if (size <= 8)
m_8_listhead = (addr_t)log; fListhead8 = (addr_t)logicalAddress;
else if ( size <= 16 ) else if (size <= 16)
m_16_listhead = (addr_t)log; fListhead16 = (addr_t)logicalAddress;
else if ( size <= 32 ) else if (size <= 32)
m_32_listhead = (addr_t)log; fListhead32 = (addr_t)logicalAddress;
Unlock(); Unlock();
return B_OK; return B_OK;
} }
area_id Stack::AllocateArea( void **log , void **phy , size_t size , const char *name )
{
physical_entry pe;
void * logadr;
area_id areaid;
status_t rv;
dprintf(MODULE_NAME"allocating %ld bytes for %s\n",size,name);
area_id
Stack::AllocateArea(void **logicalAddress, void **physicalAddress, size_t size,
const char *name)
{
TRACE(("usb stack: allocating %ld bytes for %s\n", size, name));
void *logAddress;
size = (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); size = (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
areaid = create_area(name, &logadr, B_ANY_KERNEL_ADDRESS,size,B_FULL_LOCK | B_CONTIGUOUS, 0 ); area_id area = create_area(name, &logAddress, B_ANY_KERNEL_ADDRESS, size,
if (areaid < B_OK) { B_FULL_LOCK | B_CONTIGUOUS, 0);
dprintf(MODULE_NAME"couldn't allocate area %s\n",name);
if (area < B_OK) {
TRACE(("usb stack: couldn't allocate area %s\n", name));
return B_ERROR; return B_ERROR;
} }
rv = get_memory_map(logadr,size,&pe,1);
if (rv < B_OK) { physical_entry physicalEntry;
delete_area(areaid); status_t result = get_memory_map(logAddress, size, &physicalEntry, 1);
dprintf(MODULE_NAME"couldn't map %s\n",name); if (result < B_OK) {
delete_area(area);
TRACE(("usb stack: couldn't map area %s\n", name));
return B_ERROR; return B_ERROR;
} }
memset(logadr,0,size);
if (log) memset(logAddress, 0, size);
*log = logadr; if (logicalAddress)
if (phy) *logicalAddress = logAddress;
*phy = pe.address;
dprintf(MODULE_NAME"area = %ld, size = %ld, log = 0x%08x, phy = 0x%08x\n",areaid,size,(uint32)logadr,(uint32)(pe.address)); if (physicalAddress)
return areaid; *physicalAddress = physicalEntry.address;
TRACE(("usb stack: area = 0x%08x, size = %ld, log = 0x%08x, phy = 0x%08x\n",
area, size, logAddress, physicalEntry.address));
return area;
} }
Stack *data = 0;
Stack *usb_stack = NULL;

View File

@ -1,95 +1,101 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2003-2004, Niels S. Reedijk * Copyright 2003-2006, Haiku Inc. All rights reserved.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * Niels S. Reedijk
// the rights to use, copy, modify, merge, publish, distribute, sublicense, */
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#include "usb_p.h" #include "usb_p.h"
Transfer::Transfer( Pipe *pipe , bool synchronous )
Transfer::Transfer(Pipe *pipe, bool synchronous)
{ {
m_pipe = pipe; fPipe = pipe;
m_buffer = 0; fBuffer = NULL;
m_bufferlength = 0; fBufferLength = 0;
m_actual_length = 0; fActualLength = NULL;
m_timeout = 0; fTimeout = 0;
m_status = 0; fStatus = B_ERROR;
m_sem = B_ERROR; fSem = -1;
m_hcpriv = 0; fHostPrivate = NULL;
if ( synchronous == true ) if (synchronous) {
{ fSem = create_sem(0, "USB Transfer");
m_sem = create_sem( 0 , "USB Transfer" ); set_sem_owner(fSem, B_SYSTEM_TEAM);
set_sem_owner ( m_sem , B_SYSTEM_TEAM );
} }
} }
Transfer::~Transfer() Transfer::~Transfer()
{ {
if ( m_sem > B_OK ) if (fSem >= B_OK)
delete_sem( m_sem ); delete_sem(fSem);
} }
void Transfer::SetRequestData( usb_request_data *data )
void
Transfer::SetRequestData(usb_request_data *data)
{ {
m_request = data; fRequest = data;
} }
void Transfer::SetBuffer( uint8 *buffer )
void
Transfer::SetBuffer(uint8 *buffer)
{ {
m_buffer = buffer; fBuffer = buffer;
} }
void Transfer::SetBufferLength( size_t length )
void
Transfer::SetBufferLength(size_t length)
{ {
m_bufferlength = length; fBufferLength = length;
} }
void Transfer::SetActualLength( size_t *actual_length )
{
m_actual_length = actual_length;
};
void Transfer::SetCallbackFunction( usb_callback_func callback ) void
Transfer::SetActualLength(size_t *actualLength)
{ {
m_callback = callback; fActualLength = actualLength;
} }
void Transfer::SetHostPrivate( hostcontroller_priv *priv )
void
Transfer::SetCallbackFunction(usb_callback_func callback)
{ {
m_hcpriv = priv; fCallback = callback;
} }
void Transfer::WaitForFinish()
{
if ( m_sem > B_OK )
acquire_sem( m_sem );
}
void Transfer::TransferDone() void
Transfer::SetHostPrivate(hostcontroller_priv *priv)
{ {
if ( m_sem > B_OK ) fHostPrivate = priv;
release_sem( m_sem );
} }
void
Transfer::WaitForFinish()
{
if (fSem > B_OK)
acquire_sem(fSem);
// ToDo: and otherwise?
}
void
Transfer::TransferDone()
{
if (fSem > B_OK)
release_sem(fSem);
}
void Transfer::Finish() void Transfer::Finish()
{ {
//If we are synchronous, release a sem // If we are synchronous, release a sem
if ( m_sem > B_OK ) if (fSem > B_OK)
release_sem( m_sem ); release_sem(fSem);
} }

View File

@ -1,109 +1,95 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2003-2004, Niels S. Reedijk * Copyright 2003-2006, Haiku Inc. All rights reserved.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * Niels S. Reedijk
// the rights to use, copy, modify, merge, publish, distribute, sublicense, */
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#include <USB.h> #include <USB.h>
#include <util/kernel_cpp.h> #include <util/kernel_cpp.h>
#include "usb_p.h" #include "usb_p.h"
#define USB_DEBUG
#ifdef USB_DEBUG #define TRACE_USB
#define TRACE dprintf #ifdef TRACE_USB
#define TRACE(x) dprintf x
#else #else
#define TRACE silent #define TRACE(x) /* nothing */
void silent( const char * , ... ) {}
#endif #endif
/* ++++++++++
Loading/unloading the module
++++++++++ */
static int32 static int32
bus_std_ops(int32 op, ...) bus_std_ops(int32 op, ...)
{ {
Stack *stack; switch (op) {
switch(op) { case B_MODULE_INIT: {
case B_MODULE_INIT: #ifdef TRACE_USB
#ifdef USB_DEBUG set_dprintf_enabled(true);
set_dprintf_enabled( true ); load_driver_symbols("usb");
load_driver_symbols( "usb" ); #endif
#endif
TRACE(("usb_nielx: bus module: init\n")); TRACE(("usb_nielx: bus module: init\n"));
stack = new Stack();
if( stack->InitCheck() != B_OK ) Stack *stack = new Stack();
{ if (stack->InitCheck() != B_OK) {
delete stack; delete stack;
return ENODEV; return ENODEV;
} }
break; break;
}
case B_MODULE_UNINIT: case B_MODULE_UNINIT:
TRACE(("usb_nielx: bus module: uninit\n")); TRACE(("usb_nielx: bus module: uninit\n"));
delete data; delete usb_stack;
break; break;
default: default:
return EINVAL; return EINVAL;
} }
return B_OK; return B_OK;
} }
/* ++++++++++ /*
This module exports the USB API This module exports the USB API
++++++++++ */ */
struct usb_module_info gModuleInfo = {
struct usb_module_info m_module_info =
{
// First the bus_manager_info: // First the bus_manager_info:
{ {
//module_info
{ {
"bus_managers/usb/nielx" , "bus_managers/usb/nielx",
B_KEEP_LOADED , // Keep loaded, even if no driver requires it B_KEEP_LOADED, // Keep loaded, even if no driver requires it
bus_std_ops bus_std_ops
} , },
NULL // the rescan function NULL // the rescan function
} , },
NULL , // register_driver
NULL , // install_notify NULL, // register_driver
NULL , // uninstall_notify NULL, // install_notify
NULL , // get_device_descriptor NULL, // uninstall_notify
NULL , // get_nth_configuration_info NULL, // get_device_descriptor
NULL , // get_configuration NULL, // get_nth_configuration_info
NULL , // set_configuration NULL, // get_configuration
NULL , // set_alt_interface NULL, // set_configuration
NULL , // set_feature NULL, // set_alt_interface
NULL , // clear_feature NULL, // set_feature
NULL , // get_status NULL, // clear_feature
NULL , // get_descriptor NULL, // get_status
NULL , // send_request NULL, // get_descriptor
NULL , // queue_interrupt NULL, // send_request
NULL , // queue_bulk NULL, // queue_interrupt
NULL , // queue_isochronous NULL, // queue_bulk
NULL , // queue_request NULL, // queue_isochronous
NULL , // set_pipe_policy NULL, // queue_request
NULL , // cancel_queued_transfers NULL, // set_pipe_policy
NULL, // cancel_queued_transfers
NULL // usb_ioctl NULL // usb_ioctl
}; };
module_info *modules[] = { module_info *modules[] = {
(module_info *)&m_module_info , (module_info *)&gModuleInfo,
NULL NULL
}; };

View File

@ -1,128 +1,126 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2003-2004, Niels S. Reedijk * Copyright 2003-2006, Haiku Inc. All rights reserved.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * Niels S. Reedijk
// the rights to use, copy, modify, merge, publish, distribute, sublicense, */
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef USB_P #ifndef _USB_P_
#define USB_P #define _USB_P_
#include "usbspec_p.h" #include "usbspec_p.h"
/* ++++++++++
Forward declarations
++++++++++ */
class Stack; class Stack;
class Device; class Device;
class Transfer; class Transfer;
class BusManager; class BusManager;
class ControlPipe; class ControlPipe;
/* ++++++++++
The host_controller_info struct host_controller_info {
++++++++++ */ module_info info;
struct host_controller_info status_t (*control)(uint32 op, void *data, size_t length);
{ bool (*add_to)(Stack &stack);
module_info info;
status_t (*control)(uint32 op, void *data, size_t length);
bool (*add_to)(Stack &stack);
}; };
/* ++++++++++ class Stack {
Internal classes
++++++++++ */
class Stack
{
public: public:
Stack(); Stack();
~Stack(); ~Stack();
status_t InitCheck();
status_t InitCheck();
void Lock();
void Unlock(); void Lock();
void Unlock();
void AddBusManager( BusManager *bus );
void AddBusManager(BusManager *bus);
status_t AllocateChunk( void **log , void **phy , uint8 size );
status_t FreeChunk( void *log , void *phy , uint8 size ); status_t AllocateChunk(void **logicalAddress,
area_id AllocateArea( void **log , void **phy , size_t size , const char *name ); void **physicalAddress, uint8 size);
status_t FreeChunk(void *logicalAddress,
void *physicalAddress, uint8 size);
area_id AllocateArea(void **logicalAddress,
void **physicalAddress,
size_t size, const char *name);
private: private:
Vector<BusManager *> m_busmodules;//Stores all the bus modules Vector<BusManager *> fBusManagers;
sem_id m_master; //The master lock
sem_id m_datalock; //Lock that controls data transfers sem_id fMasterLock;
area_id m_areas[USB_MAX_AREAS]; //Stores the area_id for the memory pool sem_id fDataLock;
void *m_logical[USB_MAX_AREAS];//Stores the logical base addresses
void *m_physical[USB_MAX_AREAS];//Stores the physical base addresses area_id fAreas[USB_MAX_AREAS];
uint16 m_areafreecount[USB_MAX_AREAS]; //Keeps track of how many free chunks there are void *fLogical[USB_MAX_AREAS];
addr_t m_8_listhead; void *fPhysical[USB_MAX_AREAS];
addr_t m_16_listhead; uint16 fAreaFreeCount[USB_MAX_AREAS];
addr_t m_32_listhead;
addr_t fListhead8;
addr_t fListhead16;
addr_t fListhead32;
}; };
extern "C" Stack *data; extern "C" Stack *usb_stack;
class Device class Device {
{
friend class Pipe;
public: public:
Device( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum , bool speed); Device(BusManager *bus, Device *parent,
virtual bool IsHub() { return false; }; usb_device_descriptor &desc,
status_t InitCheck(); int8 deviceAddress, bool lowSpeed);
uint8 GetAddress() { return m_devicenum; }; status_t InitCheck();
int16 GetDescriptor( uint8 descriptor_type , uint16 index , void *buffer ,
size_t size ); virtual bool IsHub() { return false; };
BusManager *GetBusManager() { return m_bus; }; int8 Address() { return fDeviceAddress; };
status_t SetConfiguration( uint8 value ); BusManager *Manager() { return fBus; };
size_t GetDescriptor(uint8 descriptorType,
uint16 index, void *buffer,
size_t bufferSize);
status_t SetConfiguration(uint8 value);
protected: protected:
usb_device_descriptor m_device_descriptor; friend class Pipe;
usb_configuration_descriptor * m_configurations;
usb_configuration_descriptor * m_current_configuration; usb_device_descriptor fDeviceDescriptor;
ControlPipe * m_defaultPipe; usb_configuration_descriptor *fConfigurations;
bool m_initok; usb_configuration_descriptor *fCurrentConfiguration;
bool m_lowspeed; ControlPipe *fDefaultPipe;
BusManager * m_bus; bool fInitOK;
Device * m_parent; bool fLowSpeed;
int8 m_devicenum; BusManager *fBus;
uint8 m_maxpacketin[16]; //Max. size of input Device *fParent;
uint8 m_maxpacketout[16]; //Max size of output int8 fDeviceAddress;
sem_id m_lock; uint8 fMaxPacketIn[16];
uint8 fMaxPacketOut[16];
sem_id fLock;
}; };
class Hub : public Device
{ class Hub : public Device {
public: public:
Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum , bool lowspeed ); Hub(BusManager *bus, Device *parent,
virtual bool IsHub() { return true; }; usb_device_descriptor &desc,
int8 deviceAddress, bool lowSpeed);
void Explore(); virtual bool IsHub() { return true; };
private:
usb_interface_descriptor m_interrupt_interface; void Explore();
usb_endpoint_descriptor m_interrupt_endpoint;
usb_hub_descriptor m_hub_descriptor; private:
usb_interface_descriptor fInterruptInterface;
usb_port_status m_port_status[8]; //Max of 8 ports, for the moment usb_endpoint_descriptor fInterruptEndpoint;
Device *m_children[8]; usb_hub_descriptor fHubDescriptor;
usb_port_status fPortStatus[8];
Device *fChildren[8];
}; };
/* /*
* This class manages a bus. It is created by the Stack object * This class manages a bus. It is created by the Stack object
* after a host controller gives positive feedback on whether the hardware * after a host controller gives positive feedback on whether the hardware
@ -171,7 +169,6 @@ static int32 ExploreThread(void *data);
* The Pipe class is the communication management between the hardware and\ * The Pipe class is the communication management between the hardware and\
* the stack. It creates packets, manages these and performs callbacks. * the stack. It creates packets, manages these and performs callbacks.
*/ */
class Pipe { class Pipe {
public: public:
enum pipeDirection { In, Out, Default }; enum pipeDirection { In, Out, Default };
@ -203,6 +200,7 @@ class ControlPipe : public Pipe {
public: public:
ControlPipe(Device *device, ControlPipe(Device *device,
pipeDirection direction, pipeDirection direction,
pipeSpeed speed,
uint8 endpointAddress); uint8 endpointAddress);
// Constructor for default control pipe // Constructor for default control pipe
@ -232,11 +230,11 @@ private:
pipeSpeed fSpeed; pipeSpeed fSpeed;
}; };
/* /*
* This is a forward definition of a struct that is defined in the individual * This is a forward definition of a struct that is defined in the individual
* host controller modules * host controller modules
*/ */
struct hostcontroller_priv; struct hostcontroller_priv;
@ -245,46 +243,49 @@ struct hostcontroller_priv;
* packets. The class is only used in the bus_manager: the host controllers * packets. The class is only used in the bus_manager: the host controllers
* receive the internal data structures. * receive the internal data structures.
*/ */
class Transfer {
class Transfer
{
public: public:
Transfer( Pipe *pipe , bool synchronous ); Transfer(Pipe *pipe, bool synchronous);
~Transfer(); ~Transfer();
void SetRequestData( usb_request_data *data );
void SetBuffer( uint8 *buffer );
void SetBufferLength( size_t length );
void SetActualLength( size_t * );
void SetCallbackFunction( usb_callback_func callback );
void SetHostPrivate( hostcontroller_priv *priv );
void WaitForFinish();
void TransferDone();
void Finish();
Pipe *GetPipe() { return m_pipe; };
uint8 *GetBuffer() { return m_buffer; };
size_t GetBufferLength() { return m_bufferlength; };
size_t *GetActualLength() { return m_actual_length; };
usb_request_data *GetRequestData() { return m_request; };
hostcontroller_priv *GetHostPrivate() { return m_hcpriv; };
private:
//Data that is related to the transfer
Pipe *m_pipe;
uint8 *m_buffer;
size_t m_bufferlength;
size_t *m_actual_length;
bigtime_t m_timeout;
status_t m_status;
usb_callback_func m_callback;
sem_id m_sem;
hostcontroller_priv *m_hcpriv;
//For control transfers Pipe *TransferPipe() { return fPipe; };
usb_request_data *m_request;
void SetRequestData(usb_request_data *data);
usb_request_data *RequestData() { return fRequest; };
void SetBuffer(uint8 *buffer);
uint8 *Buffer() { return fBuffer; };
void SetBufferLength(size_t length);
size_t BufferLength() { return fBufferLength; };
void SetActualLength(size_t *actualLength);
size_t *ActualLength() { return fActualLength; };
void SetHostPrivate(hostcontroller_priv *priv);
hostcontroller_priv *HostPrivate() { return fHostPrivate; };
void SetCallbackFunction(usb_callback_func callback);
void WaitForFinish();
void TransferDone();
void Finish();
private:
// Data that is related to the transfer
Pipe *fPipe;
uint8 *fBuffer;
size_t fBufferLength;
size_t *fActualLength;
bigtime_t fTimeout;
status_t fStatus;
usb_callback_func fCallback;
sem_id fSem;
hostcontroller_priv *fHostPrivate;
// For control transfers
usb_request_data *fRequest;
}; };
#endif #endif

View File

@ -1,26 +1,13 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2003-2005, Niels S. Reedijk * Copyright 2003-2006, Haiku Inc. All rights reserved.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * Niels S. Reedijk
// the rights to use, copy, modify, merge, publish, distribute, sublicense, */
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef USBSPEC_P #ifndef _USBSPEC_P_
#define USBSPEC_P #define _USBSPEC_P_
#include <KernelExport.h> #include <KernelExport.h>
#include <util/Vector.h> #include <util/Vector.h>
@ -28,17 +15,19 @@
#include <util/kernel_cpp.h> #include <util/kernel_cpp.h>
#define USB_MAX_AREAS 8 #define USB_MAX_AREAS 8
#define POWER_DELAY
/*
Important data from the USB spec (not interesting for drivers)
*/
struct memory_chunk struct memory_chunk
{ {
addr_t next_item; addr_t next_item;
addr_t physical; addr_t physical;
}; };
/* ++++++++++
Important data from the USB spec (not interesting for drivers)
++++++++++ */
#define POWER_DELAY
struct usb_request_data struct usb_request_data
{ {
@ -49,6 +38,7 @@ struct usb_request_data
uint16 Length; uint16 Length;
}; };
struct usb_hub_descriptor struct usb_hub_descriptor
{ {
uint8 bDescLength; uint8 bDescLength;
@ -63,6 +53,7 @@ struct usb_hub_descriptor
#define USB_DESCRIPTOR_HUB 0x29 #define USB_DESCRIPTOR_HUB 0x29
// USB Spec 1.1 page 273 // USB Spec 1.1 page 273
struct usb_port_status struct usb_port_status
{ {
@ -70,29 +61,31 @@ struct usb_port_status
uint16 change; uint16 change;
}; };
//The bits in the usb_port_status struct //The bits in the usb_port_status struct
// USB 1.1 spec page 274 // USB 1.1 spec page 274
#define PORT_STATUS_CONNECTION 0x1 #define PORT_STATUS_CONNECTION 0x0001
#define PORT_STATUS_ENABLE 0x2 #define PORT_STATUS_ENABLE 0x0002
#define PORT_STATUS_SUSPEND 0x4 #define PORT_STATUS_SUSPEND 0x0004
#define PORT_STATUS_OVER_CURRENT 0x8 #define PORT_STATUS_OVER_CURRENT 0x0008
#define PORT_STATUS_RESET 0x10 #define PORT_STATUS_RESET 0x0010
#define PORT_STATUS_POWER 0x100 #define PORT_STATUS_POWER 0x0100
#define PORT_STATUS_LOW_SPEED 0x200 #define PORT_STATUS_LOW_SPEED 0x0200
//The feature requests with ports //The feature requests with ports
// USB 1.1 spec page 268 // USB 1.1 spec page 268
#define PORT_CONNECTION 0 #define PORT_CONNECTION 0
#define PORT_ENABLE 1 #define PORT_ENABLE 1
#define PORT_SUSPEND 2 #define PORT_SUSPEND 2
#define PORT_OVER_CURRENT 3 #define PORT_OVER_CURRENT 3
#define PORT_RESET 4 #define PORT_RESET 4
#define PORT_POWER 8 #define PORT_POWER 8
#define PORT_LOW_SPEED 9 #define PORT_LOW_SPEED 9
#define C_PORT_CONNECTION 16 #define C_PORT_CONNECTION 16
#define C_PORT_ENABLE 17 #define C_PORT_ENABLE 17
#define C_PORT_SUSPEND 18 #define C_PORT_SUSPEND 18
#define C_PORT_OVER_CURRENT 19 #define C_PORT_OVER_CURRENT 19
#define C_PORT_RESET 20 #define C_PORT_RESET 20
#endif #endif

View File

@ -154,7 +154,7 @@ free_descriptor_chain(uhci_td *topDescriptor, Stack *stack)
size_t size_t
read_descriptor_chain(uhci_td *topDescriptor, uint8 *buffer, int32 bufferSize) read_descriptor_chain(uhci_td *topDescriptor, uint8 *buffer, int32 bufferSize)
{ {
TRACE(("usb_uhci: reading descriptor chain to buffer 0x%08x\n", buffer, bufferSize)); TRACE(("usb_uhci: reading descriptor chain to buffer 0x%08x\n", buffer));
size_t actualSize = 0; size_t actualSize = 0;
uhci_td *current = topDescriptor; uhci_td *current = topDescriptor;
@ -162,7 +162,7 @@ read_descriptor_chain(uhci_td *topDescriptor, uint8 *buffer, int32 bufferSize)
if (!current->buffer_log) if (!current->buffer_log)
break; break;
size_t length = (current->status & TD_STATUS_ACTLEN_MASK) + 1; int32 length = (current->status & TD_STATUS_ACTLEN_MASK) + 1;
if (length == TD_STATUS_ACTLEN_NULL + 1) if (length == TD_STATUS_ACTLEN_NULL + 1)
length = 0; length = 0;
@ -323,8 +323,8 @@ Queue::AppendDescriptor(uhci_td *descriptor)
status_t status_t
Queue::AddRequest(Transfer *transfer, bigtime_t timeout) Queue::AddRequest(Transfer *transfer, bigtime_t timeout)
{ {
Pipe *pipe = transfer->GetPipe(); Pipe *pipe = transfer->TransferPipe();
usb_request_data *requestData = transfer->GetRequestData(); usb_request_data *requestData = transfer->RequestData();
bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) > 0; bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) > 0;
uhci_td *setupDescriptor = new_descriptor(fStack, pipe, TD_TOKEN_SETUP, uhci_td *setupDescriptor = new_descriptor(fStack, pipe, TD_TOKEN_SETUP,
@ -345,9 +345,9 @@ Queue::AddRequest(Transfer *transfer, bigtime_t timeout)
statusDescriptor->link_phy = QH_TERMINATE; statusDescriptor->link_phy = QH_TERMINATE;
statusDescriptor->link_log = 0; statusDescriptor->link_log = 0;
if (transfer->GetBuffer() && transfer->GetBufferLength() > 0) { if (transfer->Buffer() && transfer->BufferLength() > 0) {
int32 packetSize = 8; int32 packetSize = 8;
int32 bufferLength = transfer->GetBufferLength(); int32 bufferLength = transfer->BufferLength();
int32 descriptorCount = (bufferLength + packetSize - 1) / packetSize; int32 descriptorCount = (bufferLength + packetSize - 1) / packetSize;
bool dataToggle = true; bool dataToggle = true;
@ -415,9 +415,9 @@ Queue::AddRequest(Transfer *transfer, bigtime_t timeout)
// without any error so we finished successfully // without any error so we finished successfully
TRACE(("usb_uhci: transfer successful\n")); TRACE(("usb_uhci: transfer successful\n"));
uint8 *buffer = (uint8 *)transfer->GetBuffer(); uint8 *buffer = (uint8 *)transfer->Buffer();
int32 bufferSize = transfer->GetBufferLength(); int32 bufferSize = transfer->BufferLength();
size_t *actualLength = transfer->GetActualLength(); size_t *actualLength = transfer->ActualLength();
if (buffer && bufferSize > 0) { if (buffer && bufferSize > 0) {
*actualLength = read_descriptor_chain( *actualLength = read_descriptor_chain(
(uhci_td *)setupDescriptor->link_log, (uhci_td *)setupDescriptor->link_log,
@ -620,10 +620,10 @@ UHCI::SubmitTransfer(Transfer *transfer, bigtime_t timeout)
TRACE(("usb_uhci: submit packet called\n")); TRACE(("usb_uhci: submit packet called\n"));
// Short circuit the root hub // Short circuit the root hub
if (transfer->GetPipe()->DeviceAddress() == fRootHubAddress) if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress)
return fRootHub->SubmitTransfer(transfer); return fRootHub->SubmitTransfer(transfer);
if (transfer->GetPipe()->Type() == Pipe::Control) if (transfer->TransferPipe()->Type() == Pipe::Control)
return fQueues[1]->AddRequest(transfer, timeout); return fQueues[1]->AddRequest(transfer, timeout);
return B_ERROR; return B_ERROR;

View File

@ -95,7 +95,7 @@ UHCIRootHub::UHCIRootHub(UHCI *uhci, int8 devicenum)
status_t status_t
UHCIRootHub::SubmitTransfer(Transfer *transfer) UHCIRootHub::SubmitTransfer(Transfer *transfer)
{ {
usb_request_data *request = transfer->GetRequestData(); usb_request_data *request = transfer->RequestData();
TRACE(("usb_uhci_roothub: rh_submit_packet called. request: %u\n", request->Request)); TRACE(("usb_uhci_roothub: rh_submit_packet called. request: %u\n", request->Request));
status_t result = B_ERROR; status_t result = B_ERROR;
@ -103,7 +103,7 @@ UHCIRootHub::SubmitTransfer(Transfer *transfer)
case RH_GET_STATUS: case RH_GET_STATUS:
if (request->Index == 0) { if (request->Index == 0) {
// Get the hub status -- everything as 0 means all-right // Get the hub status -- everything as 0 means all-right
memset(transfer->GetBuffer(), 0, sizeof(get_status_buffer)); memset(transfer->Buffer(), 0, sizeof(get_status_buffer));
result = B_OK; result = B_OK;
break; break;
} else if (request->Index > uhci_hubd.bNbrPorts) { } else if (request->Index > uhci_hubd.bNbrPorts) {
@ -114,11 +114,11 @@ UHCIRootHub::SubmitTransfer(Transfer *transfer)
// Get port status // Get port status
UpdatePortStatus(); UpdatePortStatus();
memcpy(transfer->GetBuffer(), memcpy(transfer->Buffer(),
(void *)&fPortStatus[request->Index - 1], (void *)&fPortStatus[request->Index - 1],
transfer->GetBufferLength()); transfer->BufferLength());
*(transfer->GetActualLength()) = transfer->GetBufferLength(); *(transfer->ActualLength()) = transfer->BufferLength();
result = B_OK; result = B_OK;
break; break;
@ -137,33 +137,33 @@ UHCIRootHub::SubmitTransfer(Transfer *transfer)
switch (request->Value) { switch (request->Value) {
case RH_DEVICE_DESCRIPTOR: case RH_DEVICE_DESCRIPTOR:
memcpy(transfer->GetBuffer(), (void *)&uhci_devd, memcpy(transfer->Buffer(), (void *)&uhci_devd,
transfer->GetBufferLength()); transfer->BufferLength());
*(transfer->GetActualLength()) = transfer->GetBufferLength(); *(transfer->ActualLength()) = transfer->BufferLength();
result = B_OK; result = B_OK;
break; break;
case RH_CONFIG_DESCRIPTOR: case RH_CONFIG_DESCRIPTOR:
memcpy(transfer->GetBuffer(), (void *)&uhci_confd, memcpy(transfer->Buffer(), (void *)&uhci_confd,
transfer->GetBufferLength()); transfer->BufferLength());
*(transfer->GetActualLength()) = transfer->GetBufferLength(); *(transfer->ActualLength()) = transfer->BufferLength();
result = B_OK; result = B_OK;
break; break;
case RH_INTERFACE_DESCRIPTOR: case RH_INTERFACE_DESCRIPTOR:
memcpy(transfer->GetBuffer(), (void *)&uhci_intd, memcpy(transfer->Buffer(), (void *)&uhci_intd,
transfer->GetBufferLength()); transfer->BufferLength());
*(transfer->GetActualLength()) = transfer->GetBufferLength(); *(transfer->ActualLength()) = transfer->BufferLength();
result = B_OK ; result = B_OK ;
break; break;
case RH_ENDPOINT_DESCRIPTOR: case RH_ENDPOINT_DESCRIPTOR:
memcpy(transfer->GetBuffer(), (void *)&uhci_endd, memcpy(transfer->Buffer(), (void *)&uhci_endd,
transfer->GetBufferLength()); transfer->BufferLength());
*(transfer->GetActualLength()) = transfer->GetBufferLength(); *(transfer->ActualLength()) = transfer->BufferLength();
result = B_OK ; result = B_OK ;
break; break;
case RH_HUB_DESCRIPTOR: case RH_HUB_DESCRIPTOR:
memcpy(transfer->GetBuffer(), (void *)&uhci_hubd, memcpy(transfer->Buffer(), (void *)&uhci_hubd,
transfer->GetBufferLength()); transfer->BufferLength());
*(transfer->GetActualLength()) = transfer->GetBufferLength(); *(transfer->ActualLength()) = transfer->BufferLength();
result = B_OK; result = B_OK;
break; break;
default: default: