diff --git a/src/add-ons/kernel/bus_managers/usb/BusManager.cpp b/src/add-ons/kernel/bus_managers/usb/BusManager.cpp index 7bbeb82046..2fcedbcbe1 100644 --- a/src/add-ons/kernel/bus_managers/usb/BusManager.cpp +++ b/src/add-ons/kernel/bus_managers/usb/BusManager.cpp @@ -70,6 +70,7 @@ BusManager::ExploreThread(void *data) return B_ERROR; while (true) { + //snooze(5000000); rootHub->Explore(); snooze(1000000); } diff --git a/src/add-ons/kernel/bus_managers/usb/Device.cpp b/src/add-ons/kernel/bus_managers/usb/Device.cpp index f64e70e547..3994b13e6c 100644 --- a/src/add-ons/kernel/bus_managers/usb/Device.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Device.cpp @@ -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; - - m_bus = bus; - m_parent = parent; - m_initok = false; - m_configurations = 0; - m_current_configuration = 0; - - 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" ); + fBus = bus; + fParent = parent; + fInitOK = false; + fCurrentConfiguration = NULL; + fDeviceAddress = deviceAddress; + + TRACE(("USB Device: new device\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; - - //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 ); - - //4. Get the device descriptor + + set_sem_owner(fLock, B_SYSTEM_TEAM); + + 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); + + // 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 ) ); - - if ( retval != sizeof( m_device_descriptor ) ) - { - dprintf( "usb Device: error while getting the device descriptor\n" ); + status_t status = GetDescriptor(USB_DESCRIPTOR_DEVICE, 0, + (void *)&fDeviceDescriptor, sizeof(fDeviceDescriptor)); + + 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 ); - - // 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" ); + + 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)); + + // 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 ); - - //6. TODO: Find drivers for the device - - m_initok = true; + + // Set default configuration + TRACE(("USB Device %d: setting default configuration\n", fDeviceAddress)); + SetConfiguration(0); + + // 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 ) -{ - 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 - m_current_configuration = m_configurations + value; +status_t +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; } diff --git a/src/add-ons/kernel/bus_managers/usb/Hub.cpp b/src/add-ons/kernel/bus_managers/usb/Hub.cpp index 3e05f26927..57a4aeeaa1 100644 --- a/src/add-ons/kernel/bus_managers/usb/Hub.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Hub.cpp @@ -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 ) -{ - dprintf( "USB Hub is being initialised\n" ); - size_t actual_length; - if ( m_initok == false ) - { - dprintf( "Hub::Hub() Device failed to initialize\n" ); +#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) +{ + TRACE(("USB Hub is being initialised\n")); + + if (!fInitOK) { + TRACE(("USB Hub: Device failed to initialize\n")); return; } - - //Set to false again for the hub init. - m_initok = false; - - if( m_device_descriptor.device_subclass != 0 || m_device_descriptor.device_protocol != 0 ) - { - dprintf( "USB Hub: wrong class/subclass/protocol! Bailing out\n" ); + + // Set to false again for the hub init. + fInitOK = false; + + 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 ); - - //We're basically done now - m_initok = true; - dprintf( "USB Hub: initialised ok\n" ); + 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); + } + + // Wait for power to stabilize + snooze(fHubDescriptor.bPwrOn2PwrGood * 2); + + fInitOK = true; + TRACE(("USB Hub: initialised ok\n")); } -void Hub::Explore() + +void +Hub::Explore() { - size_t actual_length; - - for ( int i = 0 ; i < m_hub_descriptor.bNbrPorts ; i++ ) - { + 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 - - 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 - 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; + newDevice = fBus->AllocateNewDevice(this, false); + + if (newDevice) + fChildren[i] = newDevice; + } else { + // Device removed... + // ToDo: do something + TRACE(("USB Hub Explore(): Device removed\n")); } - else - { - //Device removed... - //DO something - dprintf( "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); + } + } } diff --git a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp index 71111ac69c..d1f0cd6f67 100644 --- a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp @@ -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(); } diff --git a/src/add-ons/kernel/bus_managers/usb/Stack.cpp b/src/add-ons/kernel/bus_managers/usb/Stack.cpp index a4aa67e72a..1c67987661 100644 --- a/src/add-ons/kernel/bus_managers/usb/Stack.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Stack.cpp @@ -1,284 +1,296 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2003-2004, 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 -// 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 #include - #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 ); - - //Create the data lock - m_datalock = create_sem( 1 , "usb data lock" ); - set_sem_owner( m_datalock , B_SYSTEM_TEAM ); + TRACE(("usb stack: stack init\n")); - //Set the global "data" variable to this - data = this; + // Create the master lock + 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 - 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::Iterator i = m_busmodules.Begin() ; i != m_busmodules.End() ; i++ ) + for (Vector::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] ); -} - + } -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 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; - - 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; - + chunk->physical = (addr_t)physicalAddress; + + 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 ) -{ - 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); - 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; diff --git a/src/add-ons/kernel/bus_managers/usb/Transfer.cpp b/src/add-ons/kernel/bus_managers/usb/Transfer.cpp index 7524680049..6a5882f4db 100644 --- a/src/add-ons/kernel/bus_managers/usb/Transfer.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Transfer.cpp @@ -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 ) + +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 ); + 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() -{ - if ( m_sem > B_OK ) - acquire_sem( m_sem ); -} -void Transfer::TransferDone() +void +Transfer::SetHostPrivate(hostcontroller_priv *priv) { - if ( m_sem > B_OK ) - release_sem( m_sem ); + fHostPrivate = priv; } + +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() { - //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); } diff --git a/src/add-ons/kernel/bus_managers/usb/usb.cpp b/src/add-ons/kernel/bus_managers/usb/usb.cpp index 0f61d3e1cf..f9a992ed84 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb.cpp +++ b/src/add-ons/kernel/bus_managers/usb/usb.cpp @@ -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 #include - #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 }; 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 4faed3656d..e7d15b3db6 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb_p.h +++ b/src/add-ons/kernel/bus_managers/usb/usb_p.h @@ -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 -{ - module_info info; - status_t (*control)(uint32 op, void *data, size_t length); - bool (*add_to)(Stack &stack); + +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 ); - - 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 ); + Stack(); + ~Stack(); + + status_t InitCheck(); + + void Lock(); + void Unlock(); + + void AddBusManager(BusManager *bus); + + 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 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 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; }; - 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 ); + Device(BusManager *bus, Device *parent, + usb_device_descriptor &desc, + int8 deviceAddress, bool lowSpeed); + + status_t InitCheck(); + +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); - 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]; +virtual bool IsHub() { return true; }; + + void Explore(); + +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(); - 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; + Transfer(Pipe *pipe, bool synchronous); + ~Transfer(); - //For control transfers - usb_request_data *m_request; + 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(); + +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 - diff --git a/src/add-ons/kernel/bus_managers/usb/usbspec_p.h b/src/add-ons/kernel/bus_managers/usb/usbspec_p.h index 40b94de8ee..3eac90052b 100644 --- a/src/add-ons/kernel/bus_managers/usb/usbspec_p.h +++ b/src/add-ons/kernel/bus_managers/usb/usbspec_p.h @@ -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 #include @@ -28,17 +15,19 @@ #include #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,29 +61,31 @@ 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 -#define PORT_CONNECTION 0 -#define PORT_ENABLE 1 -#define PORT_SUSPEND 2 -#define PORT_OVER_CURRENT 3 -#define PORT_RESET 4 -#define PORT_POWER 8 -#define PORT_LOW_SPEED 9 -#define C_PORT_CONNECTION 16 -#define C_PORT_ENABLE 17 -#define C_PORT_SUSPEND 18 -#define C_PORT_OVER_CURRENT 19 -#define C_PORT_RESET 20 +#define PORT_CONNECTION 0 +#define PORT_ENABLE 1 +#define PORT_SUSPEND 2 +#define PORT_OVER_CURRENT 3 +#define PORT_RESET 4 +#define PORT_POWER 8 +#define PORT_LOW_SPEED 9 +#define C_PORT_CONNECTION 16 +#define C_PORT_ENABLE 17 +#define C_PORT_SUSPEND 18 +#define C_PORT_OVER_CURRENT 19 +#define C_PORT_RESET 20 -#endif \ No newline at end of file +#endif diff --git a/src/add-ons/kernel/busses/usb/uhci.cpp b/src/add-ons/kernel/busses/usb/uhci.cpp index 1efdd6b3ab..2a124fdfa7 100644 --- a/src/add-ons/kernel/busses/usb/uhci.cpp +++ b/src/add-ons/kernel/busses/usb/uhci.cpp @@ -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; diff --git a/src/add-ons/kernel/busses/usb/uhci_rh.cpp b/src/add-ons/kernel/busses/usb/uhci_rh.cpp index deb3dade0a..7ec63451d6 100644 --- a/src/add-ons/kernel/busses/usb/uhci_rh.cpp +++ b/src/add-ons/kernel/busses/usb/uhci_rh.cpp @@ -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: