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;
while (true) {
//snooze(5000000);
rootHub->Explore();
snooze(1000000);
}

View File

@ -1,129 +1,138 @@
//------------------------------------------------------------------------------
// Copyright (c) 2003-2004, Niels S. Reedijk
//
// Permission is hereby granted, free of charge, to any person obtaining a
// 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.
/*
* Copyright 2003-2006, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Niels S. Reedijk
*/
#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;
fInitOK = false;
fCurrentConfiguration = NULL;
fDeviceAddress = deviceAddress;
m_bus = bus;
m_parent = parent;
m_initok = false;
m_configurations = 0;
m_current_configuration = 0;
TRACE(("USB Device: new device\n"));
dprintf( "USB Device: new device\n" );
//1. Create the semaphore
m_lock = create_sem( 1 , "device_sem" );
if ( m_lock < B_OK )
{
dprintf( "usb Device: could not create semaphore\n" );
fLock = create_sem(1, "USB Device Lock");
if (fLock < B_OK) {
TRACE(("USB Device: could not create semaphore\n"));
return;
}
set_sem_owner( m_lock , B_SYSTEM_TEAM );
//2. Set the free entry free entry in the device map (for the device number)
m_devicenum = devicenum;
set_sem_owner(fLock, B_SYSTEM_TEAM);
//3. Set up the pipe stuff
//Set the maximum transfer numbers for the incoming and the outgoing packets on endpoint 0
m_maxpacketin[0] = m_maxpacketout[0] = m_device_descriptor.max_packet_size_0;
m_device_descriptor = desc;
m_lowspeed = lowspeed;
m_defaultPipe = new ControlPipe( this , Pipe::Default , 0 );
fLowSpeed = lowSpeed;
fDeviceDescriptor = desc;
fMaxPacketIn[0] = fMaxPacketOut[0] = fDeviceDescriptor.max_packet_size_0;
fDefaultPipe = new ControlPipe(this, Pipe::Default,
lowSpeed ? Pipe::LowSpeed : Pipe::NormalSpeed, 0);
//4. Get the device descriptor
// Get the device descriptor
// We already have a part of it, but we want it all
retval = GetDescriptor( USB_DESCRIPTOR_DEVICE , 0 ,
(void *)&m_device_descriptor , sizeof(m_device_descriptor ) );
status_t status = GetDescriptor(USB_DESCRIPTOR_DEVICE, 0,
(void *)&fDeviceDescriptor, sizeof(fDeviceDescriptor));
if ( retval != sizeof( m_device_descriptor ) )
{
dprintf( "usb Device: error while getting the device descriptor\n" );
if (status != sizeof(fDeviceDescriptor)) {
TRACE(("USB Device: error while getting the device descriptor\n"));
return;
}
dprintf( "usb Device %d: Vendor id: %d , Product id: %d\n" , devicenum ,
m_device_descriptor.vendor_id , m_device_descriptor.product_id );
TRACE(("USB Device %d: Vendor id: 0x%04x, Product id: 0x%04x, Device version: 0x%04x\n",
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) );
if ( m_configurations == 0 )
{
dprintf( "usb Device: out of memory during config creations!\n" );
// Get the configurations
fConfigurations = (usb_configuration_descriptor *)malloc(fDeviceDescriptor.num_configurations
* sizeof(usb_configuration_descriptor));
if (fConfigurations == NULL) {
TRACE(("USB Device: out of memory during config creations!\n"));
return;
}
for ( int i = 0 ; i < m_device_descriptor.num_configurations ; i++ )
{
if ( GetDescriptor( USB_DESCRIPTOR_CONFIGURATION , i ,
(void *)( m_configurations + i ) , sizeof (usb_configuration_descriptor ) ) != sizeof( usb_configuration_descriptor ) )
{
dprintf( "usb Device %d: error fetching configuration %d ...\n" , m_devicenum , i );
for (int32 i = 0; i < fDeviceDescriptor.num_configurations; i++) {
size_t size = GetDescriptor(USB_DESCRIPTOR_CONFIGURATION, i,
(void *)&fConfigurations[i], sizeof(usb_configuration_descriptor));
if (size != sizeof(usb_configuration_descriptor)) {
TRACE(("USB Device %d: error fetching configuration %d\n", fDeviceAddress, i));
return;
}
}
// 5. Set the default configuration
dprintf( "usb Device %d: setting configuration %d\n" , m_devicenum , 0 );
SetConfiguration( 0 );
// Set default configuration
TRACE(("USB Device %d: setting default configuration\n", fDeviceAddress));
SetConfiguration(0);
//6. TODO: Find drivers for the device
m_initok = true;
// ToDo: Find drivers for the device
fInitOK = 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 )
status_t
Device::InitCheck()
{
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;
if (fInitOK)
return B_OK;
return B_ERROR;
}
status_t Device::SetConfiguration( uint8 value )
// 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)
{
if ( value >= m_device_descriptor.num_configurations )
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;
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
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
//Set current configuration
m_current_configuration = m_configurations + value;
if (result < B_OK)
return result;
// Set current configuration
fCurrentConfiguration = &fConfigurations[value];
return B_OK;
}

View File

@ -1,192 +1,174 @@
//------------------------------------------------------------------------------
// Copyright (c) 2003-2004, Niels S. Reedijk
//
// Permission is hereby granted, free of charge, to any person obtaining a
// 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.
/*
* Copyright 2003-2006, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Niels S. Reedijk
*/
#include "usb_p.h"
Hub::Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum , bool lowspeed )
: Device ( bus , parent , desc , devicenum , lowspeed )
#define TRACE_HUB
#ifdef TRACE_HUB
#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)
{
dprintf( "USB Hub is being initialised\n" );
size_t actual_length;
TRACE(("USB Hub is being initialised\n"));
if ( m_initok == false )
{
dprintf( "Hub::Hub() Device failed to initialize\n" );
if (!fInitOK) {
TRACE(("USB Hub: Device failed to initialize\n"));
return;
}
//Set to false again for the hub init.
m_initok = false;
// Set to false again for the hub init.
fInitOK = false;
if( m_device_descriptor.device_subclass != 0 || m_device_descriptor.device_protocol != 0 )
{
dprintf( "USB Hub: wrong class/subclass/protocol! Bailing out\n" );
if (fDeviceDescriptor.device_subclass != 0
|| fDeviceDescriptor.device_protocol != 0) {
TRACE(("USB Hub: wrong class/subclass/protocol! Bailing out\n"));
return;
}
if ( m_current_configuration->number_interfaces > 1 )
{
dprintf( "USB Hub: too much interfaces! Bailing out\n" );
if (fCurrentConfiguration->number_interfaces > 1) {
TRACE(("USB Hub: too many interfaces\n"));
return;
}
dprintf( "USB Hub this: %p" , this );
if ( GetDescriptor( USB_DESCRIPTOR_INTERFACE , 0 ,
(void *)&m_interrupt_interface ,
sizeof (usb_interface_descriptor) ) != sizeof( usb_interface_descriptor ) )
{
dprintf( "USB Hub: error getting the interrupt interface! Bailing out.\n" );
size_t actualLength;
if (GetDescriptor(USB_DESCRIPTOR_INTERFACE, 0, (void *)&fInterruptInterface,
sizeof(usb_interface_descriptor)) != sizeof(usb_interface_descriptor)) {
TRACE(("USB Hub: error getting the interrupt interface\n"));
return;
}
if ( m_interrupt_interface.num_endpoints > 1 )
{
dprintf( "USB Hub: too much endpoints! Bailing out.\n" );
if (fInterruptInterface.num_endpoints > 1) {
TRACE(("USB Hub: too many endpoints\n"));
return;
}
if ( GetDescriptor( USB_DESCRIPTOR_ENDPOINT , 0 ,
(void *)&m_interrupt_endpoint ,
sizeof (usb_endpoint_descriptor) ) != sizeof (usb_endpoint_descriptor ) )
{
dprintf( "USB Hub: Error getting the endpoint. Bailing out\n" );
if (GetDescriptor(USB_DESCRIPTOR_ENDPOINT, 0, (void *)&fInterruptEndpoint,
sizeof(usb_endpoint_descriptor)) != sizeof(usb_endpoint_descriptor)) {
TRACE(("USB Hub: Error getting the endpoint\n"));
return;
}
if ( m_interrupt_endpoint.attributes != 0x03 ) //interrupt transfer
{
dprintf( "USB Hub: Not an interrupt endpoint. Bailing out\n" );
if (fInterruptEndpoint.attributes != 0x03) { // interrupt transfer
TRACE(("USB Hub: Not an interrupt endpoint\n"));
return;
}
dprintf( "USB Hub: Getting hub descriptor...\n" );
if ( GetDescriptor( USB_DESCRIPTOR_HUB , 0 ,
(void *)&m_hub_descriptor ,
sizeof (usb_hub_descriptor) ) != sizeof (usb_hub_descriptor ) )
{
dprintf( "USB Hub: Error getting hub descriptor\n" );
TRACE(("USB Hub: Getting hub descriptor...\n"));
if (GetDescriptor(USB_DESCRIPTOR_HUB, 0, (void *)&fHubDescriptor,
sizeof(usb_hub_descriptor)) != sizeof(usb_hub_descriptor)) {
TRACE(("USB Hub: Error getting hub descriptor\n"));
return;
}
// Enable port power on all ports
for ( int i = 0 ; i < m_hub_descriptor.bNbrPorts ; i++ )
m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT ,
USB_REQUEST_SET_FEATURE ,
PORT_POWER ,
i + 1 , //index
0 ,
NULL ,
0 ,
&actual_length );
//Wait for power to stabilize
snooze( m_hub_descriptor.bPwrOn2PwrGood * 2 );
for (int32 i = 0; i < fHubDescriptor.bNbrPorts; i++) {
fDefaultPipe->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
USB_REQUEST_SET_FEATURE,
PORT_POWER,
i + 1,
0,
NULL,
0,
&actualLength);
}
//We're basically done now
m_initok = true;
dprintf( "USB Hub: initialised ok\n" );
// Wait for power to stabilize
snooze(fHubDescriptor.bPwrOn2PwrGood * 2);
fInitOK = true;
TRACE(("USB Hub: initialised ok\n"));
}
void Hub::Explore()
{
size_t actual_length;
for ( int i = 0 ; i < m_hub_descriptor.bNbrPorts ; i++ )
{
void
Hub::Explore()
{
for (int32 i = 0; i < fHubDescriptor.bNbrPorts; i++) {
size_t actualLength;
// Get the current port status
m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_IN ,
USB_REQUEST_GET_STATUS ,
0 , //Value
i + 1 , //Index
4 , //length
(void *)&m_port_status[i],
4 ,
&actual_length );
if ( actual_length < 4 )
{
dprintf( "USB Hub: ERROR getting port status\n" );
fDefaultPipe->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_IN,
USB_REQUEST_GET_STATUS,
0,
i + 1,
4,
(void *)&fPortStatus[i],
4,
&actualLength);
if (actualLength < 4) {
TRACE(("USB Hub: error getting port status\n"));
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
//TRACE(("status: 0x%04x; change: 0x%04x\n", fPortStatus[i].status, fPortStatus[i].change));
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 );
// 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 ( 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) {
if ((fPortStatus[i].status & PORT_STATUS_ENABLE) == 0) {
// enable the port if it isn't
m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT ,
USB_REQUEST_SET_FEATURE ,
PORT_ENABLE ,
i + 1 , //index
0 ,
NULL ,
0 ,
&actual_length );
fDefaultPipe->SendRequest(
USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
USB_REQUEST_SET_FEATURE,
PORT_ENABLE,
i + 1,
0,
NULL,
0,
NULL);
}
dprintf( "USB Hub Explore(): New device connected\n" );
Device *newdev;
if ( m_port_status[i].status & PORT_STATUS_LOW_SPEED )
newdev = m_bus->AllocateNewDevice( this , true );
TRACE(("USB Hub: Explore(): New device connected\n"));
Device *newDevice;
if (fPortStatus[i].status & PORT_STATUS_LOW_SPEED)
newDevice = fBus->AllocateNewDevice(this, true);
else
newdev = m_bus->AllocateNewDevice( this , false );
if ( newdev != 0 )
m_children[i] = newdev;
}
else
{
//Device removed...
//DO something
dprintf( "USB Hub Explore(): Device removed\n" );
newDevice = fBus->AllocateNewDevice(this, false);
if (newDevice)
fChildren[i] = newDevice;
} else {
// Device removed...
// ToDo: do something
TRACE(("USB Hub Explore(): Device removed\n"));
}
//Clear status
m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT ,
USB_REQUEST_CLEAR_FEATURE ,
C_PORT_CONNECTION ,
i + 1 , //index
0 ,
NULL ,
0 ,
&actual_length );
} // PORT_STATUS_CONNECTION
}//for (...)
// Clear status change
fDefaultPipe->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
USB_REQUEST_CLEAR_FEATURE,
C_PORT_CONNECTION,
i + 1,
0,
NULL,
0,
NULL);
}
}
}

View File

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

View File

@ -1,284 +1,296 @@
//------------------------------------------------------------------------------
// Copyright (c) 2003-2004, Niels S. Reedijk
//
// AllocArea implementation (c) 2002 Marcus Overhagen <marcus@overhagen.de>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// 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.
/*
* Copyright 2003-2006, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Niels S. Reedijk
*/
#include <module.h>
#include <util/kernel_cpp.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()
{
dprintf(MODULE_NAME"stack init\n");
//Init the master lock
m_master = create_sem( 1 , "usb master lock" );
set_sem_owner( m_master , B_SYSTEM_TEAM );
TRACE(("usb stack: stack init\n"));
//Create the data lock
m_datalock = create_sem( 1 , "usb data lock" );
set_sem_owner( m_datalock , B_SYSTEM_TEAM );
// Create the master lock
fMasterLock = create_sem(1, "usb master lock");
set_sem_owner(fMasterLock, B_SYSTEM_TEAM);
//Set the global "data" variable to this
data = this;
// Create the data lock
fDataLock = create_sem(1, "usb data lock");
set_sem_owner(fDataLock, B_SYSTEM_TEAM);
//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.
// 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.
// 8-byte heap
m_areafreecount[0] = 0;
m_areas[0] = AllocateArea( &m_logical[0] , &m_physical[0] , B_PAGE_SIZE ,
"8-byte chunk area" );
if ( m_areas[0] < B_OK )
{
dprintf(MODULE_NAME"8-byte chunk area failed to initialise\n" );
fAreaFreeCount[0] = 0;
fAreas[0] = AllocateArea(&fLogical[0], &fPhysical[0], B_PAGE_SIZE,
"8-byte chunk area");
if (fAreas[0] < B_OK) {
TRACE(("usb stack: 8-byte chunk area failed to initialise\n"));
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++ )
{
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 );
if (i < B_PAGE_SIZE / 8 - 1)
chunk->next_item = (addr_t)fLogical[0] + 8 * (i + 1);
else
chunk->next_item = NULL;
}
// 16-byte heap
m_areafreecount[1] = 0;
m_areas[1] = AllocateArea( &m_logical[1] , &m_physical[1] , B_PAGE_SIZE ,
"16-byte chunk area" );
if ( m_areas[1] < B_OK )
{
dprintf(MODULE_NAME"16-byte chunk area failed to initialise\n" );
fAreaFreeCount[1] = 0;
fAreas[1] = AllocateArea(&fLogical[1], &fPhysical[1], B_PAGE_SIZE,
"16-byte chunk area");
if (fAreas[1] < B_OK) {
TRACE(("usb stack: 16-byte chunk area failed to initialise\n"));
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++ )
{
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 );
if (i < B_PAGE_SIZE / 16 - 1)
chunk->next_item = (addr_t)fLogical[1] + 16 * (i + 1);
else
chunk->next_item = NULL;
}
// 32-byte heap
m_areafreecount[2] = 0;
m_areas[2] = AllocateArea( &m_logical[2] , &m_physical[2] , B_PAGE_SIZE ,
"32-byte chunk area" );
if ( m_areas[2] < B_OK )
{
dprintf(MODULE_NAME"32-byte chunk area failed to initialise\n" );
fAreaFreeCount[2] = 0;
fAreas[2] = AllocateArea(&fLogical[2], &fPhysical[2], B_PAGE_SIZE,
"32-byte chunk area");
if (fAreas[2] < B_OK) {
TRACE(("usb stack: 32-byte chunk area failed to initialise\n"));
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++ )
{
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 );
if (i < B_PAGE_SIZE / 32 - 1)
chunk->next_item = (addr_t)fLogical[2] + 32 * (i + 1);
else
chunk->next_item = NULL;
}
//Check for host controller modules
void *list = open_module_list( "busses/usb" );
char modulename[B_PATH_NAME_LENGTH];
size_t buffersize = sizeof(modulename);
dprintf(MODULE_NAME"Looking for host controller modules\n" );
while( read_next_module_name( list , modulename , &buffersize ) == B_OK )
{
dprintf(MODULE_NAME"Found module %s\n" , modulename );
buffersize = sizeof(modulename);
host_controller_info *module = 0;
if ( get_module( modulename , (module_info **)&module ) != B_OK )
// Check for host controller modules
void *moduleList = open_module_list("busses/usb");
char moduleName[B_PATH_NAME_LENGTH];
size_t bufferSize = sizeof(moduleName);
TRACE(("usb stack: Looking for host controller modules\n"));
while(read_next_module_name(moduleList, moduleName, &bufferSize) == B_OK) {
bufferSize = sizeof(moduleName);
TRACE(("usb stack: Found module %s\n", moduleName));
host_controller_info *module = NULL;
if (get_module(moduleName, (module_info **)&module) != B_OK)
continue;
if ( module->add_to( *this) != B_OK )
if (module->add_to(*this) != B_OK)
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;
}
Stack::~Stack()
{
//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_area( m_areas[0] );
delete_area( m_areas[1] );
delete_area( m_areas[2] );
}
delete_area(fAreas[0]);
delete_area(fAreas[1]);
delete_area(fAreas[2]);
}
status_t Stack::InitCheck()
status_t
Stack::InitCheck()
{
if ( m_busmodules.Count() == 0 )
if (fBusManagers.Count() == 0)
return ENODEV;
return B_OK;
}
void Stack::Lock()
{
acquire_sem( m_master );
}
void Stack::Unlock()
void
Stack::Lock()
{
release_sem( m_master );
}
void Stack::AddBusManager( BusManager *bus )
{
m_busmodules.PushBack( bus );
acquire_sem(fMasterLock);
}
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();
addr_t listhead;
if ( size <= 8 )
listhead = m_8_listhead;
else if ( size <= 16 )
listhead = m_16_listhead;
else if ( size <= 32 )
listhead = m_32_listhead;
else
{
dprintf (MODULE_NAME"Chunk size %i to big\n" , size );
if (size <= 8)
listhead = fListhead8;
else if (size <= 16)
listhead = fListhead16;
else if (size <= 32)
listhead = fListhead32;
else {
TRACE(("usb stack: Chunk size %d to big\n", size));
Unlock();
return B_ERROR;
}
if ( listhead == NULL )
{
if (listhead == NULL) {
TRACE(("usb stack: Out of memory on this list\n"));
Unlock();
dprintf(MODULE_NAME"Out of memory on this list\n" );
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;
*log = (void *)listhead;
*phy = (void *)(chunk->physical);
if ( chunk->next_item == NULL )
*logicalAddress = (void *)listhead;
*physicalAddress = (void *)chunk->physical;
if (chunk->next_item == NULL) {
//TODO: allocate more memory
listhead = NULL;
else
} else {
listhead = chunk->next_item;
}
//Update our listhead pointers
if ( size <= 8 )
m_8_listhead = listhead;
else if ( size <= 16 )
m_16_listhead = listhead;
else if ( size <= 32 )
m_32_listhead = listhead;
// Update our listhead pointers
if (size <= 8)
fListhead8 = listhead;
else if (size <= 16)
fListhead16 = listhead;
else if (size <= 32)
fListhead32 = listhead;
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;
}
status_t Stack::FreeChunk( void *log , void *phy , uint8 size )
status_t
Stack::FreeChunk(void *logicalAddress, void *physicalAddress, uint8 size)
{
Lock();
addr_t listhead;
if ( size <= 8 )
listhead = m_8_listhead;
else if ( size <= 16 )
listhead = m_16_listhead;
else if ( size <= 32 )
listhead = m_32_listhead;
else
{
dprintf (MODULE_NAME"Chunk size %i invalid\n" , size );
if (size <= 8)
listhead = fListhead8;
else if (size <= 16)
listhead = fListhead16;
else if (size <= 32)
listhead = fListhead32;
else {
TRACE(("usb stack: Chunk size %d invalid\n", size));
Unlock();
return B_ERROR;
}
memory_chunk *chunk = (memory_chunk *)log;
memory_chunk *chunk = (memory_chunk *)logicalAddress;
chunk->next_item = listhead;
chunk->physical = (addr_t)phy;
chunk->physical = (addr_t)physicalAddress;
if ( size <= 8 )
m_8_listhead = (addr_t)log;
else if ( size <= 16 )
m_16_listhead = (addr_t)log;
else if ( size <= 32 )
m_32_listhead = (addr_t)log;
if (size <= 8)
fListhead8 = (addr_t)logicalAddress;
else if (size <= 16)
fListhead16 = (addr_t)logicalAddress;
else if (size <= 32)
fListhead32 = (addr_t)logicalAddress;
Unlock();
return B_OK;
}
area_id Stack::AllocateArea( void **log , void **phy , size_t size , const char *name )
area_id
Stack::AllocateArea(void **logicalAddress, void **physicalAddress, 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);
TRACE(("usb stack: allocating %ld bytes for %s\n", size, name));
void *logAddress;
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 );
if (areaid < B_OK) {
dprintf(MODULE_NAME"couldn't allocate area %s\n",name);
area_id area = create_area(name, &logAddress, B_ANY_KERNEL_ADDRESS, size,
B_FULL_LOCK | B_CONTIGUOUS, 0);
if (area < B_OK) {
TRACE(("usb stack: couldn't allocate area %s\n", name));
return B_ERROR;
}
rv = get_memory_map(logadr,size,&pe,1);
if (rv < B_OK) {
delete_area(areaid);
dprintf(MODULE_NAME"couldn't map %s\n",name);
physical_entry physicalEntry;
status_t result = get_memory_map(logAddress, size, &physicalEntry, 1);
if (result < B_OK) {
delete_area(area);
TRACE(("usb stack: couldn't map area %s\n", name));
return B_ERROR;
}
memset(logadr,0,size);
if (log)
*log = logadr;
if (phy)
*phy = pe.address;
dprintf(MODULE_NAME"area = %ld, size = %ld, log = 0x%08x, phy = 0x%08x\n",areaid,size,(uint32)logadr,(uint32)(pe.address));
return areaid;
memset(logAddress, 0, size);
if (logicalAddress)
*logicalAddress = logAddress;
if (physicalAddress)
*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
//
// Permission is hereby granted, free of charge, to any person obtaining a
// 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.
/*
* Copyright 2003-2006, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Niels S. Reedijk
*/
#include "usb_p.h"
Transfer::Transfer( Pipe *pipe , bool synchronous )
{
m_pipe = pipe;
m_buffer = 0;
m_bufferlength = 0;
m_actual_length = 0;
m_timeout = 0;
m_status = 0;
m_sem = B_ERROR;
m_hcpriv = 0;
if ( synchronous == true )
{
m_sem = create_sem( 0 , "USB Transfer" );
set_sem_owner ( m_sem , B_SYSTEM_TEAM );
Transfer::Transfer(Pipe *pipe, bool synchronous)
{
fPipe = pipe;
fBuffer = NULL;
fBufferLength = 0;
fActualLength = NULL;
fTimeout = 0;
fStatus = B_ERROR;
fSem = -1;
fHostPrivate = NULL;
if (synchronous) {
fSem = create_sem(0, "USB Transfer");
set_sem_owner(fSem, B_SYSTEM_TEAM);
}
}
Transfer::~Transfer()
{
if ( m_sem > B_OK )
delete_sem( m_sem );
if (fSem >= B_OK)
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()
void
Transfer::SetHostPrivate(hostcontroller_priv *priv)
{
if ( m_sem > B_OK )
acquire_sem( m_sem );
fHostPrivate = priv;
}
void Transfer::TransferDone()
void
Transfer::WaitForFinish()
{
if ( m_sem > B_OK )
release_sem( m_sem );
if (fSem > B_OK)
acquire_sem(fSem);
// ToDo: and otherwise?
}
void
Transfer::TransferDone()
{
if (fSem > B_OK)
release_sem(fSem);
}
void Transfer::Finish()
{
//If we are synchronous, release a sem
if ( m_sem > B_OK )
release_sem( m_sem );
// If we are synchronous, release a sem
if (fSem > B_OK)
release_sem(fSem);
}

View File

@ -1,109 +1,95 @@
//------------------------------------------------------------------------------
// Copyright (c) 2003-2004, Niels S. Reedijk
//
// Permission is hereby granted, free of charge, to any person obtaining a
// 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.
/*
* Copyright 2003-2006, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Niels S. Reedijk
*/
#include <USB.h>
#include <util/kernel_cpp.h>
#include "usb_p.h"
#define USB_DEBUG
#ifdef USB_DEBUG
#define TRACE dprintf
#define TRACE_USB
#ifdef TRACE_USB
#define TRACE(x) dprintf x
#else
#define TRACE silent
void silent( const char * , ... ) {}
#define TRACE(x) /* nothing */
#endif
/* ++++++++++
Loading/unloading the module
++++++++++ */
static int32
bus_std_ops(int32 op, ...)
{
Stack *stack;
switch(op) {
case B_MODULE_INIT:
#ifdef USB_DEBUG
set_dprintf_enabled( true );
load_driver_symbols( "usb" );
#endif
switch (op) {
case B_MODULE_INIT: {
#ifdef TRACE_USB
set_dprintf_enabled(true);
load_driver_symbols("usb");
#endif
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;
return ENODEV;
}
break;
}
case B_MODULE_UNINIT:
TRACE(("usb_nielx: bus module: uninit\n"));
delete data;
delete usb_stack;
break;
default:
return EINVAL;
}
return B_OK;
}
/* ++++++++++
This module exports the USB API
++++++++++ */
struct usb_module_info m_module_info =
{
/*
This module exports the USB API
*/
struct usb_module_info gModuleInfo = {
// First the bus_manager_info:
{
//module_info
{
"bus_managers/usb/nielx" ,
B_KEEP_LOADED , // Keep loaded, even if no driver requires it
"bus_managers/usb/nielx",
B_KEEP_LOADED, // Keep loaded, even if no driver requires it
bus_std_ops
} ,
},
NULL // the rescan function
} ,
NULL , // register_driver
NULL , // install_notify
NULL , // uninstall_notify
NULL , // get_device_descriptor
NULL , // get_nth_configuration_info
NULL , // get_configuration
NULL , // set_configuration
NULL , // set_alt_interface
NULL , // set_feature
NULL , // clear_feature
NULL , // get_status
NULL , // get_descriptor
NULL , // send_request
NULL , // queue_interrupt
NULL , // queue_bulk
NULL , // queue_isochronous
NULL , // queue_request
NULL , // set_pipe_policy
NULL , // cancel_queued_transfers
},
NULL, // register_driver
NULL, // install_notify
NULL, // uninstall_notify
NULL, // get_device_descriptor
NULL, // get_nth_configuration_info
NULL, // get_configuration
NULL, // set_configuration
NULL, // set_alt_interface
NULL, // set_feature
NULL, // clear_feature
NULL, // get_status
NULL, // get_descriptor
NULL, // send_request
NULL, // queue_interrupt
NULL, // queue_bulk
NULL, // queue_isochronous
NULL, // queue_request
NULL, // set_pipe_policy
NULL, // cancel_queued_transfers
NULL // usb_ioctl
};
module_info *modules[] = {
(module_info *)&m_module_info ,
(module_info *)&gModuleInfo,
NULL
};

View File

@ -1,128 +1,126 @@
//------------------------------------------------------------------------------
// Copyright (c) 2003-2004, Niels S. Reedijk
//
// Permission is hereby granted, free of charge, to any person obtaining a
// 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.
/*
* Copyright 2003-2006, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Niels S. Reedijk
*/
#ifndef USB_P
#define USB_P
#ifndef _USB_P_
#define _USB_P_
#include "usbspec_p.h"
/* ++++++++++
Forward declarations
++++++++++ */
class Stack;
class Device;
class Transfer;
class BusManager;
class ControlPipe;
/* ++++++++++
The host_controller_info
++++++++++ */
struct host_controller_info
{
struct host_controller_info {
module_info info;
status_t (*control)(uint32 op, void *data, size_t length);
bool (*add_to)(Stack &stack);
};
/* ++++++++++
Internal classes
++++++++++ */
class Stack
{
class Stack {
public:
Stack();
~Stack();
status_t InitCheck();
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 );
area_id AllocateArea( void **log , void **phy , size_t size , const char *name );
status_t AllocateChunk(void **logicalAddress,
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:
Vector<BusManager *> m_busmodules;//Stores all the bus modules
sem_id m_master; //The master lock
sem_id m_datalock; //Lock that controls data transfers
area_id m_areas[USB_MAX_AREAS]; //Stores the area_id for the memory pool
void *m_logical[USB_MAX_AREAS];//Stores the logical base addresses
void *m_physical[USB_MAX_AREAS];//Stores the physical base addresses
uint16 m_areafreecount[USB_MAX_AREAS]; //Keeps track of how many free chunks there are
addr_t m_8_listhead;
addr_t m_16_listhead;
addr_t m_32_listhead;
Vector<BusManager *> fBusManagers;
sem_id fMasterLock;
sem_id fDataLock;
area_id fAreas[USB_MAX_AREAS];
void *fLogical[USB_MAX_AREAS];
void *fPhysical[USB_MAX_AREAS];
uint16 fAreaFreeCount[USB_MAX_AREAS];
addr_t fListhead8;
addr_t fListhead16;
addr_t fListhead32;
};
extern "C" Stack *data;
extern "C" Stack *usb_stack;
class Device
{
friend class Pipe;
class Device {
public:
Device( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum , bool speed);
virtual bool IsHub() { return false; };
Device(BusManager *bus, Device *parent,
usb_device_descriptor &desc,
int8 deviceAddress, bool lowSpeed);
status_t InitCheck();
uint8 GetAddress() { return m_devicenum; };
int16 GetDescriptor( uint8 descriptor_type , uint16 index , void *buffer ,
size_t size );
BusManager *GetBusManager() { return m_bus; };
status_t SetConfiguration( uint8 value );
virtual bool IsHub() { return false; };
int8 Address() { return fDeviceAddress; };
BusManager *Manager() { return fBus; };
size_t GetDescriptor(uint8 descriptorType,
uint16 index, void *buffer,
size_t bufferSize);
status_t SetConfiguration(uint8 value);
protected:
usb_device_descriptor m_device_descriptor;
usb_configuration_descriptor * m_configurations;
usb_configuration_descriptor * m_current_configuration;
ControlPipe * m_defaultPipe;
bool m_initok;
bool m_lowspeed;
BusManager * m_bus;
Device * m_parent;
int8 m_devicenum;
uint8 m_maxpacketin[16]; //Max. size of input
uint8 m_maxpacketout[16]; //Max size of output
sem_id m_lock;
friend class Pipe;
usb_device_descriptor fDeviceDescriptor;
usb_configuration_descriptor *fConfigurations;
usb_configuration_descriptor *fCurrentConfiguration;
ControlPipe *fDefaultPipe;
bool fInitOK;
bool fLowSpeed;
BusManager *fBus;
Device *fParent;
int8 fDeviceAddress;
uint8 fMaxPacketIn[16];
uint8 fMaxPacketOut[16];
sem_id fLock;
};
class Hub : public Device
{
class Hub : public Device {
public:
Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum , bool lowspeed );
virtual bool IsHub() { return true; };
Hub(BusManager *bus, Device *parent,
usb_device_descriptor &desc,
int8 deviceAddress, bool lowSpeed);
virtual bool IsHub() { return true; };
void Explore();
private:
usb_interface_descriptor m_interrupt_interface;
usb_endpoint_descriptor m_interrupt_endpoint;
usb_hub_descriptor m_hub_descriptor;
usb_port_status m_port_status[8]; //Max of 8 ports, for the moment
Device *m_children[8];
private:
usb_interface_descriptor fInterruptInterface;
usb_endpoint_descriptor fInterruptEndpoint;
usb_hub_descriptor fHubDescriptor;
usb_port_status fPortStatus[8];
Device *fChildren[8];
};
/*
* This class manages a bus. It is created by the Stack object
* 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 stack. It creates packets, manages these and performs callbacks.
*/
class Pipe {
public:
enum pipeDirection { In, Out, Default };
@ -203,6 +200,7 @@ class ControlPipe : public Pipe {
public:
ControlPipe(Device *device,
pipeDirection direction,
pipeSpeed speed,
uint8 endpointAddress);
// Constructor for default control pipe
@ -232,11 +230,11 @@ private:
pipeSpeed fSpeed;
};
/*
* This is a forward definition of a struct that is defined in the individual
* host controller modules
*/
struct hostcontroller_priv;
@ -245,46 +243,49 @@ struct hostcontroller_priv;
* packets. The class is only used in the bus_manager: the host controllers
* receive the internal data structures.
*/
class Transfer
{
class Transfer {
public:
Transfer( Pipe *pipe , bool synchronous );
Transfer(Pipe *pipe, bool synchronous);
~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 );
Pipe *TransferPipe() { return fPipe; };
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();
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;
// 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 m_callback;
sem_id m_sem;
hostcontroller_priv *m_hcpriv;
usb_callback_func fCallback;
sem_id fSem;
hostcontroller_priv *fHostPrivate;
//For control transfers
usb_request_data *m_request;
// For control transfers
usb_request_data *fRequest;
};
#endif

View File

@ -1,26 +1,13 @@
//------------------------------------------------------------------------------
// Copyright (c) 2003-2005, Niels S. Reedijk
//
// Permission is hereby granted, free of charge, to any person obtaining a
// 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.
/*
* Copyright 2003-2006, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Niels S. Reedijk
*/
#ifndef USBSPEC_P
#define USBSPEC_P
#ifndef _USBSPEC_P_
#define _USBSPEC_P_
#include <KernelExport.h>
#include <util/Vector.h>
@ -28,17 +15,19 @@
#include <util/kernel_cpp.h>
#define USB_MAX_AREAS 8
#define POWER_DELAY
/*
Important data from the USB spec (not interesting for drivers)
*/
struct memory_chunk
{
addr_t next_item;
addr_t physical;
};
/* ++++++++++
Important data from the USB spec (not interesting for drivers)
++++++++++ */
#define POWER_DELAY
struct usb_request_data
{
@ -49,6 +38,7 @@ struct usb_request_data
uint16 Length;
};
struct usb_hub_descriptor
{
uint8 bDescLength;
@ -63,6 +53,7 @@ struct usb_hub_descriptor
#define USB_DESCRIPTOR_HUB 0x29
// USB Spec 1.1 page 273
struct usb_port_status
{
@ -70,15 +61,17 @@ struct usb_port_status
uint16 change;
};
//The bits in the usb_port_status struct
// USB 1.1 spec page 274
#define PORT_STATUS_CONNECTION 0x1
#define PORT_STATUS_ENABLE 0x2
#define PORT_STATUS_SUSPEND 0x4
#define PORT_STATUS_OVER_CURRENT 0x8
#define PORT_STATUS_RESET 0x10
#define PORT_STATUS_POWER 0x100
#define PORT_STATUS_LOW_SPEED 0x200
#define PORT_STATUS_CONNECTION 0x0001
#define PORT_STATUS_ENABLE 0x0002
#define PORT_STATUS_SUSPEND 0x0004
#define PORT_STATUS_OVER_CURRENT 0x0008
#define PORT_STATUS_RESET 0x0010
#define PORT_STATUS_POWER 0x0100
#define PORT_STATUS_LOW_SPEED 0x0200
//The feature requests with ports
// USB 1.1 spec page 268

View File

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

View File

@ -95,7 +95,7 @@ UHCIRootHub::UHCIRootHub(UHCI *uhci, int8 devicenum)
status_t
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));
status_t result = B_ERROR;
@ -103,7 +103,7 @@ UHCIRootHub::SubmitTransfer(Transfer *transfer)
case RH_GET_STATUS:
if (request->Index == 0) {
// 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;
break;
} else if (request->Index > uhci_hubd.bNbrPorts) {
@ -114,11 +114,11 @@ UHCIRootHub::SubmitTransfer(Transfer *transfer)
// Get port status
UpdatePortStatus();
memcpy(transfer->GetBuffer(),
memcpy(transfer->Buffer(),
(void *)&fPortStatus[request->Index - 1],
transfer->GetBufferLength());
transfer->BufferLength());
*(transfer->GetActualLength()) = transfer->GetBufferLength();
*(transfer->ActualLength()) = transfer->BufferLength();
result = B_OK;
break;
@ -137,33 +137,33 @@ UHCIRootHub::SubmitTransfer(Transfer *transfer)
switch (request->Value) {
case RH_DEVICE_DESCRIPTOR:
memcpy(transfer->GetBuffer(), (void *)&uhci_devd,
transfer->GetBufferLength());
*(transfer->GetActualLength()) = transfer->GetBufferLength();
memcpy(transfer->Buffer(), (void *)&uhci_devd,
transfer->BufferLength());
*(transfer->ActualLength()) = transfer->BufferLength();
result = B_OK;
break;
case RH_CONFIG_DESCRIPTOR:
memcpy(transfer->GetBuffer(), (void *)&uhci_confd,
transfer->GetBufferLength());
*(transfer->GetActualLength()) = transfer->GetBufferLength();
memcpy(transfer->Buffer(), (void *)&uhci_confd,
transfer->BufferLength());
*(transfer->ActualLength()) = transfer->BufferLength();
result = B_OK;
break;
case RH_INTERFACE_DESCRIPTOR:
memcpy(transfer->GetBuffer(), (void *)&uhci_intd,
transfer->GetBufferLength());
*(transfer->GetActualLength()) = transfer->GetBufferLength();
memcpy(transfer->Buffer(), (void *)&uhci_intd,
transfer->BufferLength());
*(transfer->ActualLength()) = transfer->BufferLength();
result = B_OK ;
break;
case RH_ENDPOINT_DESCRIPTOR:
memcpy(transfer->GetBuffer(), (void *)&uhci_endd,
transfer->GetBufferLength());
*(transfer->GetActualLength()) = transfer->GetBufferLength();
memcpy(transfer->Buffer(), (void *)&uhci_endd,
transfer->BufferLength());
*(transfer->ActualLength()) = transfer->BufferLength();
result = B_OK ;
break;
case RH_HUB_DESCRIPTOR:
memcpy(transfer->GetBuffer(), (void *)&uhci_hubd,
transfer->GetBufferLength());
*(transfer->GetActualLength()) = transfer->GetBufferLength();
memcpy(transfer->Buffer(), (void *)&uhci_hubd,
transfer->BufferLength());
*(transfer->ActualLength()) = transfer->BufferLength();
result = B_OK;
break;
default: