From 0f6609e85c6573eadcfc4b6fa0acaa847e313680 Mon Sep 17 00:00:00 2001 From: Niels Sascha Reedijk Date: Fri, 28 May 2004 07:46:35 +0000 Subject: [PATCH] * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-5 Commit (in between) because of a switch of development-machines * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-6 Implement basic hub init * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-7 Implement a bit more of hub operation * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-8 Device Adress 0 is reserved for the default pipe! * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-9 Implement basic Pipe stuff * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-10 Create basic chunk allocation * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-11 Add Required util.c/util.h * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-12 Provide locking for the stack and make AllocateChunk thread-safe * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-13 Integrated util.c in stack class (cleans up a little) * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-14 Improve Pipe and give the Busmanager its default pipe * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-15 Make the Device class speed aware * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-16 Make Chunk allocation code more dynamic * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-17 Small test-commit to test if webdav is working -- ignore * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-18 Changed Packets into Transfers * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-19 Fix mistakes in host_controller.c * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-20 Advanced a little more in the Pipe stuff * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-21 Merge with mainline and add newlines at the end of files git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7668 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/bus_managers/usb/BusManager.cpp | 65 ++----- .../kernel/bus_managers/usb/Device.cpp | 20 +-- src/add-ons/kernel/bus_managers/usb/Hub.cpp | 25 ++- src/add-ons/kernel/bus_managers/usb/Jamfile | 3 +- src/add-ons/kernel/bus_managers/usb/Pipe.cpp | 95 ++++++++++ src/add-ons/kernel/bus_managers/usb/Stack.cpp | 168 ++++++++++++++++++ .../usb/{Packet.cpp => Transfer.cpp} | 29 ++- .../kernel/bus_managers/usb/host_controller.h | 44 +++-- src/add-ons/kernel/bus_managers/usb/usb.rdef | 2 +- src/add-ons/kernel/bus_managers/usb/usb_p.h | 95 +++++++--- 10 files changed, 429 insertions(+), 117 deletions(-) create mode 100644 src/add-ons/kernel/bus_managers/usb/Pipe.cpp rename src/add-ons/kernel/bus_managers/usb/{Packet.cpp => Transfer.cpp} (76%) diff --git a/src/add-ons/kernel/bus_managers/usb/BusManager.cpp b/src/add-ons/kernel/bus_managers/usb/BusManager.cpp index 8d9440eaf3..19b9b74ae3 100644 --- a/src/add-ons/kernel/bus_managers/usb/BusManager.cpp +++ b/src/add-ons/kernel/bus_managers/usb/BusManager.cpp @@ -34,7 +34,7 @@ int32 usb_explore_thread( void *data ) { //Go to the hubs roothub->Explore(); - snooze(10000); //Wait one second before continueing + snooze(1000000); //Wait one second before continueing } return B_OK; } @@ -55,8 +55,12 @@ BusManager::BusManager( host_controller_info *info ) // Clear the device map memset( &m_devicemap , false , 128 ); + // Set up the default pipes + m_defaultPipe = new ControlPipe( this , 0 , Default , NormalSpeed , 0 ); + m_defaultLowSpeedPipe = new ControlPipe( this , 0 , Default , LowSpeed , 0 ); + // Set up the new root hub - AllocateNewDevice( 0 ); + AllocateNewDevice( 0 , false ); if( m_roothub == 0 ) return; @@ -82,7 +86,7 @@ status_t BusManager::InitCheck() return B_ERROR; } -Device * BusManager::AllocateNewDevice( Device *parent ) +Device * BusManager::AllocateNewDevice( Device *parent , bool lowspeed ) { int8 devicenum; status_t retval; @@ -96,9 +100,9 @@ Device * BusManager::AllocateNewDevice( Device *parent ) return 0; } + //2. Set the address of the device USB 1.1 spec p202 (bepdf) - retval = SendRequest( 0 , - USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD , //host->device + retval = m_defaultPipe->SendRequest( USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD , //host->device USB_REQUEST_SET_ADDRESS , //request devicenum , //value 0 , //index @@ -113,6 +117,9 @@ Device * BusManager::AllocateNewDevice( Device *parent ) return 0; } + //Create a temporary pipe + ControlPipe pipe( this , devicenum , Default , LowSpeed , 0 ); + //3. Get the device descriptor // Just retrieve the first 8 bytes of the descriptor -> minimum supported // size of any device, plus it is enough, because the device type is in @@ -120,8 +127,7 @@ Device * BusManager::AllocateNewDevice( Device *parent ) size_t actual_length; - SendRequest( 0 , - USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD , //Type + pipe.SendRequest( USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD , //Type USB_REQUEST_GET_DESCRIPTOR , //Request ( USB_DESCRIPTOR_DEVICE << 8 ), //Value 0 , //Index @@ -140,21 +146,21 @@ Device * BusManager::AllocateNewDevice( Device *parent ) if ( device_descriptor.device_class == 0x09 ) { dprintf( "usb Busmanager [new device]: New hub\n" ); - Device *ret = new Hub( this , parent , device_descriptor , devicenum ); + Device *ret = new Hub( this , parent , device_descriptor , devicenum , lowspeed ); if ( parent == 0 ) //root hub!! m_roothub = ret; return ret; } dprintf( "usb Busmanager [new device]: New normal device\n" ); - return new Device( this , parent , device_descriptor , devicenum ); + return new Device( this , parent , device_descriptor , devicenum , lowspeed); } int8 BusManager::AllocateAddress() { acquire_sem_etc( m_lock , 1 , B_CAN_INTERRUPT , 0 ); int8 devicenum = -1; - for( int i = 0 ; i < 128 ; i++ ) + for( int i = 1 ; i < 128 ; i++ ) { if ( m_devicemap[i] == false ) { @@ -167,42 +173,3 @@ int8 BusManager::AllocateAddress() return devicenum; } -status_t BusManager::SendRequest( Device * dev , uint8 request_type , uint8 request , uint16 value , - uint16 index , uint16 length , void *data , - size_t data_len , size_t *actual_len ) -{ - //todo: het moet speciaal soort geheugen worden - usb_request_data *req = (usb_request_data *)malloc( sizeof( usb_request_data) ); - - req->RequestType = request_type; - req->Request = request; - req->Value = value; - req->Index = index; - req->Length = length; - - //Nicen up the second argument: the default pipe - //1) set up the pipe stuff a little nicer - //2) don't assume it's a low speed device :-( - return SendControlMessage( dev , ( 2 << 30 | 1 << 26 ) , req , - data , data_len , actual_len , 3 * 1000 * 1000 ); -} - -status_t BusManager::SendControlMessage( Device *dev , uint16 pipe , - usb_request_data *command , void *data , - size_t data_length , size_t *actual_length , - bigtime_t timeout ) -{ - // this method should build an usb packet (new class) with the needed data - Packet packet; - - packet.SetPipe( pipe ); - packet.SetRequestData( (uint8 *)command ); - packet.SetBuffer( (uint8 *)data ); - packet.SetBufferLength( data_length ); - packet.SetActualLength( actual_length ); - packet.SetAddress( 0 ); - - status_t retval = hcpointer->SubmitPacket( packet.GetData() ); - return retval; -} - diff --git a/src/add-ons/kernel/bus_managers/usb/Device.cpp b/src/add-ons/kernel/bus_managers/usb/Device.cpp index 348db76da1..fcef889cc6 100644 --- a/src/add-ons/kernel/bus_managers/usb/Device.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Device.cpp @@ -21,7 +21,7 @@ #include "usb_p.h" -Device::Device( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum ) +Device::Device( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum , bool lowspeed ) { status_t retval; @@ -45,13 +45,15 @@ Device::Device( BusManager *bus , Device *parent , usb_device_descriptor &desc , //2. Set the free entry free entry in the device map (for the device number) m_devicenum = devicenum; - //3. Get the device descriptor - // We already have a part of it, but we want it all - m_device_descriptor = desc; - + //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 , Default , 0 ); + + //4. 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 ) ); @@ -95,8 +97,7 @@ int16 Device::GetDescriptor( uint8 descriptor_type , uint16 index , void *buffer , size_t size ) { size_t actual_length; - m_bus->SendRequest( this , - USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD , //Type + m_defaultPipe->SendRequest(USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD , //Type USB_REQUEST_GET_DESCRIPTOR , //Request ( descriptor_type << 8 ) | index , //Value 0 , //Index @@ -112,8 +113,7 @@ status_t Device::SetConfiguration( uint8 value ) if ( value >= m_device_descriptor.num_configurations ) return EINVAL; - m_bus->SendRequest( this , - USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD , //Type + m_defaultPipe->SendRequest( USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD , //Type USB_REQUEST_SET_CONFIGURATION , //Request value , //Value 0 , //Index diff --git a/src/add-ons/kernel/bus_managers/usb/Hub.cpp b/src/add-ons/kernel/bus_managers/usb/Hub.cpp index 8fcb786fba..d74f2ee831 100644 --- a/src/add-ons/kernel/bus_managers/usb/Hub.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Hub.cpp @@ -21,8 +21,8 @@ #include "usb_p.h" -Hub::Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum ) - : Device ( bus , parent , desc , devicenum ) +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" ); m_initok = false; // We're not yet ready! @@ -82,7 +82,7 @@ Hub::Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 // Enable port power on all ports for ( int i = 0 ; i < m_hub_descriptor.bNbrPorts ; i++ ) - m_bus->SendRequest( this , USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT , + m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT , USB_REQUEST_SET_FEATURE , PORT_POWER , i + 1 , //index @@ -104,7 +104,7 @@ void Hub::Explore() for ( int i = 0 ; i < m_hub_descriptor.bNbrPorts ; i++ ) { // Get the current port status - m_bus->SendRequest( this , USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_IN , + m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_IN , USB_REQUEST_GET_STATUS , 0 , //Value i + 1 , //Index @@ -119,6 +119,21 @@ void Hub::Explore() } //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 ) @@ -137,7 +152,7 @@ void Hub::Explore() } //Clear status - m_bus->SendRequest( this , USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT , + m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT , USB_REQUEST_CLEAR_FEATURE , C_PORT_CONNECTION , i + 1 , //index diff --git a/src/add-ons/kernel/bus_managers/usb/Jamfile b/src/add-ons/kernel/bus_managers/usb/Jamfile index b7b1f57417..69457a535d 100644 --- a/src/add-ons/kernel/bus_managers/usb/Jamfile +++ b/src/add-ons/kernel/bus_managers/usb/Jamfile @@ -10,5 +10,6 @@ R5KernelAddon usb : [ FDirName kernel bus_managers ] : Device.cpp Hub.cpp BusManager.cpp - Packet.cpp + Transfer.cpp + Pipe.cpp ; diff --git a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp new file mode 100644 index 0000000000..3d940f0dd4 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp @@ -0,0 +1,95 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 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. + +#include "usb_p.h" + +Pipe::Pipe( Device *dev , Direction &dir , uint8 &endpointaddress ) +{ + d = new usb_pipe_t; + + d->direction = dir; + m_device = dev; + + if ( m_device != NULL ) //Default pipe + { + d->deviceid = dev->m_devicenum; + if ( dev->m_lowspeed == true ) + d->speed = LowSpeed; + else + d->speed = NormalSpeed; + m_bus = m_device->m_bus; + } + d->endpoint = endpointaddress; +} + +Pipe::~Pipe() +{ + delete d; +} + +ControlPipe::ControlPipe( Device *dev , Direction dir , uint8 endpointaddress ) + : Pipe( dev , dir , endpointaddress ) +{ + +} + +ControlPipe::ControlPipe( BusManager *bus , int8 dev_id , Direction dir , Speed speed , uint8 endpointaddress ) + : Pipe( NULL , dir , endpointaddress ) +{ + m_bus = bus; + d->deviceid = dev_id; + d->speed = speed; +} + +status_t ControlPipe::SendRequest( uint8 request_type , uint8 request , uint16 value , + uint16 index , uint16 length , void *data , + size_t data_len , size_t *actual_len ) +{ + //todo: het moet speciaal soort geheugen worden + usb_request_data *req = (usb_request_data *)malloc( sizeof( usb_request_data) ); + + req->RequestType = request_type; + req->Request = request; + req->Value = value; + req->Index = index; + req->Length = length; + + //Nicen up the second argument: the default pipe + //1) set up the pipe stuff a little nicer + //2) don't assume it's a low speed device :-( + return SendControlMessage( req , data , data_len , actual_len , 3 * 1000 * 1000 ); +} + +status_t ControlPipe::SendControlMessage( usb_request_data *command , void *data , + size_t data_length , size_t *actual_length , + bigtime_t timeout ) +{ + // this method should build an usb packet (new class) with the needed data + Transfer transfer( *this ); + + transfer.SetRequestData( command ); + transfer.SetBuffer( (uint8 *)data ); + transfer.SetBufferLength( data_length ); + transfer.SetActualLength( actual_length ); + + status_t retval = m_bus->hcpointer->SubmitPacket( transfer.GetData() ); + return retval; +} \ No newline at end of file diff --git a/src/add-ons/kernel/bus_managers/usb/Stack.cpp b/src/add-ons/kernel/bus_managers/usb/Stack.cpp index 3c598a7613..ff95c5c721 100644 --- a/src/add-ons/kernel/bus_managers/usb/Stack.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Stack.cpp @@ -1,6 +1,8 @@ //------------------------------------------------------------------------------ // Copyright (c) 2003, Niels S. Reedijk // +// AllocArea implementation (c) 2002 Marcus Overhagen +// // 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 @@ -51,6 +53,57 @@ Stack::Stack() if( m_busmodules.Count() == 0 ) return; + + //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. + + + uint16 size = 0; + for ( int i = 0 ; i < 3 ; i++ ) + { + size = 2^(3+i); + dprintf( "USB: Initialising %u-byte chunk area\n" , size ); + m_areafreecount[i] = 0; + + if ( AllocArea(0) < B_OK ) + { + dprintf( "USB: %u-byte chunk area failed to initialise\n" , size ); + return; + } + + void *listhead; + + switch (size) + { + case 8: + listhead = m_8_listhead; + break; + case 16: + listhead = m_16_listhead; + break; + case 32: + listhead = m_32_listhead; + break; + default: + dprintf( "USB: Strange error: %u-byte chunks don't exist\n", size ); + return; + } + + listhead = m_logical[i]; + + for ( int j = 0 ; j < B_PAGE_SIZE/size ; j++ ) + { + memory_chunk *chunk = (memory_chunk *)((uint32)m_logical[i] + size * j); + chunk->physical = (void *)((uint32)m_physical[i] + size * j); + if ( j != B_PAGE_SIZE / size - 1 ) + chunk->next_item = (void *)((uint32)m_logical[i] + size * ( j + 1 ) ); + else + chunk->next_item = NULL; + } + } } Stack::~Stack() @@ -68,4 +121,119 @@ status_t Stack::InitCheck() return B_OK; } +void Stack::Lock() +{ + acquire_sem( m_master ); +} + +void Stack::Unlock() +{ + release_sem( m_master ); +} + +status_t Stack::AllocateChunk( void **log , void **phy , uint8 size ) +{ + Lock(); + + void *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 ( "USB Stack: Chunk size %i to big\n" , size ); + Unlock(); + return B_ERROR; + } + + if ( listhead == NULL ) + { + Unlock(); + return B_ERROR; + } + + memory_chunk *chunk = (memory_chunk *)listhead; + *log = listhead; + *phy = chunk->physical; + if ( chunk->next_item == NULL ) + //TODO: allocate more memory + listhead = NULL; + else + m_8_listhead = chunk->next_item; + Unlock(); + return B_OK; +} + +status_t Stack::FreeChunk( void *log , void *phy , uint8 size ) +{ + Lock(); + void *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 ( "USB Stack: Chunk size %i invalid\n" , size ); + Unlock(); + return B_ERROR; + } + + memory_chunk *chunk = (memory_chunk *)log; + + chunk->next_item = listhead; + chunk->physical = phy; + listhead = log; + Unlock(); + return B_OK; +} + +area_id Stack::AllocArea( void **log , void **phy , size_t size , const char *name ) +{ + physical_entry pe; + void * logadr; + area_id areaid; + status_t rv; + + dprintf("allocating %ld bytes for %s\n",size,name); + + 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, B_READ_AREA | B_WRITE_AREA); + if (areaid < B_OK) { + dprintf("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("couldn't map %s\n",name); + return B_ERROR; + } + memset(logadr,0,size); + if (log) + *log = logadr; + if (phy) + *phy = pe.address; + dprintf("area = %ld, size = %ld, log = %#08lX, phy = %#08lX\n",areaid,size,(uint32)logadr,(uint32)(pe.address)); + return areaid; +} + +//Wrapper for the above, but it works on our internal data structures +status_t Stack::AllocArea( uint8 id ) +{ + if ( id > USB_MAX_AREAS ) + return B_ERROR; + + m_areas[id] = AllocArea( &m_logical[id] , &m_physical[id] , B_PAGE_SIZE , "internal USB stack area" ); + + if ( m_areas[id] < B_OK ) + return B_ERROR; + return B_OK; +} + Stack *data = 0; diff --git a/src/add-ons/kernel/bus_managers/usb/Packet.cpp b/src/add-ons/kernel/bus_managers/usb/Transfer.cpp similarity index 76% rename from src/add-ons/kernel/bus_managers/usb/Packet.cpp rename to src/add-ons/kernel/bus_managers/usb/Transfer.cpp index 13345bdffc..2bceb1d216 100644 --- a/src/add-ons/kernel/bus_managers/usb/Packet.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Transfer.cpp @@ -21,47 +21,38 @@ #include "usb_p.h" -Packet::Packet() +Transfer::Transfer( Pipe &pipe ) { - d = new usb_packet_t; + d = new usb_transfer_t; + d->pipe = pipe.d; } -Packet::~Packet() +Transfer::~Transfer() { delete d; } -void Packet::SetPipe( uint16 pipe ) +void Transfer::SetRequestData( usb_request_data *data ) { - d->pipe = pipe; + d->request = data; } -void Packet::SetAddress( uint8 address ) -{ - d->address = address; -} - -void Packet::SetRequestData( uint8 *data ) -{ - d->requestdata = data; -} - -void Packet::SetBuffer( uint8 *buffer ) +void Transfer::SetBuffer( uint8 *buffer ) { d->buffer = buffer; } -void Packet::SetBufferLength( int16 length ) +void Transfer::SetBufferLength( int16 length ) { d->bufferlength = length; } -void Packet::SetActualLength( size_t *actual_length ) +void Transfer::SetActualLength( size_t *actual_length ) { d->actual_length = actual_length; }; -usb_packet_t * Packet::GetData() +usb_transfer_t * Transfer::GetData() { return d; } \ No newline at end of file diff --git a/src/add-ons/kernel/bus_managers/usb/host_controller.h b/src/add-ons/kernel/bus_managers/usb/host_controller.h index fe600fdbc3..c0814bf1e9 100644 --- a/src/add-ons/kernel/bus_managers/usb/host_controller.h +++ b/src/add-ons/kernel/bus_managers/usb/host_controller.h @@ -64,22 +64,42 @@ typedef struct uint16 Length; } usb_request_data; -// Describes the internal organs of an usb packet -typedef struct usb_packet_t -{ - uint16 pipe; - uint8 *requestdata; - uint8 *buffer; - int16 bufferlength; - size_t *actual_length; - int16 address; //!!!! TEMPORARY ... or is it? -} usb_packet_t; +// Describes the internals of a pipe +enum Direction { In , Out , Default }; +enum Speed { LowSpeed , NormalSpeed }; +typedef struct usb_pipe_t +{ + enum Direction direction; + enum Speed speed; + int8 deviceid; + uint8 endpoint; +} usb_pipe_t; + + +// Describes the internal organs of an usb packet +typedef struct usb_transfer_t +{ + //Data that is related to the transfer + usb_pipe_t *pipe; + uint8 *buffer; + size_t bufferlength; + size_t *actual_length; + bigtime_t timeout; + status_t status; + + //For control transfers + usb_request_data *request; +} usb_transfer_t; + +// +// typedef struct host_controller_info { module_info info; status_t (*hwstart)(void); - status_t (*SubmitPacket)(usb_packet_t *); + status_t (*SubmitPacket)(usb_transfer_t *); } host_controller_info; -#endif //HOST_CONTROLLER_INFO_H \ No newline at end of file +#endif //HOST_CONTROLLER_INFO_H + diff --git a/src/add-ons/kernel/bus_managers/usb/usb.rdef b/src/add-ons/kernel/bus_managers/usb/usb.rdef index 3116fecbf8..ed99719ad4 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb.rdef +++ b/src/add-ons/kernel/bus_managers/usb/usb.rdef @@ -14,7 +14,7 @@ resource app_version { middle = 0, minor = 1, variety = 0, - internal = 0, + internal = 1, short_info = "USB system software", long_info = "OpenBeOS - This driver is (c) 2003-2004 Niels Sascha Reedijk" }; diff --git a/src/add-ons/kernel/bus_managers/usb/usb_p.h b/src/add-ons/kernel/bus_managers/usb/usb_p.h index 08f8a023b2..0f264d25e7 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb_p.h +++ b/src/add-ons/kernel/bus_managers/usb/usb_p.h @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// Copyright (c) 2003, Niels S. Reedijk +// Copyright (c) 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"), @@ -28,11 +28,20 @@ #include "host_controller.h" #include + /* ++++++++++ Forward declarations ++++++++++ */ class Device; class BusManager; +class ControlPipe; + +#define USB_MAX_AREAS 8 +struct memory_chunk +{ + void *next_item; + void *physical; +}; /* ++++++++++ Important data from the USB spec (not interesting for drivers) @@ -50,18 +59,38 @@ public: Stack(); ~Stack(); status_t InitCheck(); + + void Lock(); + void Unlock(); + + status_t AllocateChunk( void **log , void **phy , uint8 size ); + status_t FreeChunk( void *log , void *phy , uint8 size ); + + area_id AllocArea( void **log , void **phy , size_t size , const char *name ); + private: + //Small wrapper around AllocArea + status_t AllocArea( uint8 id ); + Vector 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 + void *m_8_listhead; + void *m_16_listhead; + void *m_32_listhead; }; extern "C" Stack *data; class Device { + friend class Pipe; public: - Device( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum ); + Device( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum , bool speed); virtual bool IsHub() { return false; }; status_t InitCheck(); @@ -73,7 +102,9 @@ 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; @@ -85,7 +116,7 @@ protected: class Hub : public Device { public: - Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum); + Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum , bool lowspeed ); virtual bool IsHub() { return true; }; void Explore(); @@ -105,26 +136,21 @@ private: class BusManager { friend class Device; + friend class ControlPipe; public: BusManager( host_controller_info *info ); ~BusManager(); status_t InitCheck(); - Device *AllocateNewDevice( Device *parent ); + Device *AllocateNewDevice( Device *parent , bool speed ); int8 AllocateAddress(); - status_t SendRequest( Device *dev, uint8 request_type , uint8 request , - uint16 value , uint16 index , uint16 length , void *data , - size_t data_len , size_t *actual_len ); private: - status_t SendControlMessage( Device *dev , uint16 pipe , - usb_request_data *command , void *data , - size_t data_length , size_t *actual_length , - bigtime_t timeout ); - host_controller_info *hcpointer; bool m_initok; bool m_devicemap[128]; + ControlPipe *m_defaultLowSpeedPipe; + ControlPipe *m_defaultPipe; sem_id m_lock; Device *m_roothub; thread_id m_explore_thread; @@ -133,27 +159,56 @@ private: // Located in the BusManager.cpp int32 usb_explore_thread( 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 +{ + friend class Transfer; +public: + Pipe( Device *dev , Direction &dir , uint8 &endpointaddress ); + virtual ~Pipe(); +protected: + Device *m_device; + BusManager *m_bus; + usb_pipe_t *d; +}; + +class ControlPipe : public Pipe +{ +public: + ControlPipe( Device *dev , Direction dir , uint8 endpointaddress ); + //Special constructor for default control pipe + ControlPipe( BusManager *bus , int8 dev_id , Direction dir , Speed speed , uint8 endpointaddress ); + status_t SendRequest( uint8 request_type , uint8 request , + uint16 value , uint16 index , uint16 length , void *data , + size_t data_len , size_t *actual_len ); + status_t SendControlMessage( usb_request_data *command , void *data , + size_t data_length , size_t *actual_length , bigtime_t timeout ); +}; + /* * This class is more like an utility class that performs all functions on * packets. The class is only used in the bus_manager: the host controllers * receive the internal data structures. */ -class Packet +class Transfer { public: - Packet(); - ~Packet(); - void SetPipe( uint16 pipe ); - void SetRequestData( uint8 *data ); + Transfer( Pipe &pipe ); + ~Transfer(); + void SetRequestData( usb_request_data *data ); void SetBuffer( uint8 *buffer ); void SetBufferLength( int16 length ); - void SetAddress( uint8 address ); void SetActualLength( size_t * ); - usb_packet_t *GetData(); + usb_transfer_t *GetData(); private: - usb_packet_t *d; + usb_transfer_t *d; }; #endif +