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:
parent
64312bc94c
commit
96da8285b0
@ -70,6 +70,7 @@ BusManager::ExploreThread(void *data)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
//snooze(5000000);
|
||||||
rootHub->Explore();
|
rootHub->Explore();
|
||||||
snooze(1000000);
|
snooze(1000000);
|
||||||
}
|
}
|
||||||
|
@ -1,129 +1,138 @@
|
|||||||
//------------------------------------------------------------------------------
|
/*
|
||||||
// Copyright (c) 2003-2004, Niels S. Reedijk
|
* Copyright 2003-2006, Haiku Inc. All rights reserved.
|
||||||
//
|
* Distributed under the terms of the MIT License.
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
*
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
* Authors:
|
||||||
// to deal in the Software without restriction, including without limitation
|
* Niels S. Reedijk
|
||||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
*/
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
// Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
#include "usb_p.h"
|
#include "usb_p.h"
|
||||||
|
|
||||||
Device::Device( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum , bool lowspeed )
|
|
||||||
|
#define TRACE_USB_DEVICE
|
||||||
|
#ifdef TRACE_USB_DEVICE
|
||||||
|
#define TRACE(x) dprintf x
|
||||||
|
#else
|
||||||
|
#define TRACE(x) /* nothing */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc,
|
||||||
|
int8 deviceAddress, bool lowSpeed)
|
||||||
{
|
{
|
||||||
status_t retval;
|
fBus = bus;
|
||||||
|
fParent = parent;
|
||||||
m_bus = bus;
|
fInitOK = false;
|
||||||
m_parent = parent;
|
fCurrentConfiguration = NULL;
|
||||||
m_initok = false;
|
fDeviceAddress = deviceAddress;
|
||||||
m_configurations = 0;
|
|
||||||
m_current_configuration = 0;
|
TRACE(("USB Device: new device\n"));
|
||||||
|
|
||||||
dprintf( "USB Device: new device\n" );
|
fLock = create_sem(1, "USB Device Lock");
|
||||||
|
if (fLock < B_OK) {
|
||||||
//1. Create the semaphore
|
TRACE(("USB Device: could not create semaphore\n"));
|
||||||
m_lock = create_sem( 1 , "device_sem" );
|
|
||||||
if ( m_lock < B_OK )
|
|
||||||
{
|
|
||||||
dprintf( "usb Device: could not create semaphore\n" );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
set_sem_owner( m_lock , B_SYSTEM_TEAM );
|
|
||||||
|
set_sem_owner(fLock, B_SYSTEM_TEAM);
|
||||||
//2. Set the free entry free entry in the device map (for the device number)
|
|
||||||
m_devicenum = devicenum;
|
fLowSpeed = lowSpeed;
|
||||||
|
fDeviceDescriptor = desc;
|
||||||
//3. Set up the pipe stuff
|
fMaxPacketIn[0] = fMaxPacketOut[0] = fDeviceDescriptor.max_packet_size_0;
|
||||||
//Set the maximum transfer numbers for the incoming and the outgoing packets on endpoint 0
|
fDefaultPipe = new ControlPipe(this, Pipe::Default,
|
||||||
m_maxpacketin[0] = m_maxpacketout[0] = m_device_descriptor.max_packet_size_0;
|
lowSpeed ? Pipe::LowSpeed : Pipe::NormalSpeed, 0);
|
||||||
m_device_descriptor = desc;
|
|
||||||
m_lowspeed = lowspeed;
|
// Get the device descriptor
|
||||||
m_defaultPipe = new ControlPipe( this , Pipe::Default , 0 );
|
|
||||||
|
|
||||||
//4. Get the device descriptor
|
|
||||||
// We already have a part of it, but we want it all
|
// We already have a part of it, but we want it all
|
||||||
retval = GetDescriptor( USB_DESCRIPTOR_DEVICE , 0 ,
|
status_t status = GetDescriptor(USB_DESCRIPTOR_DEVICE, 0,
|
||||||
(void *)&m_device_descriptor , sizeof(m_device_descriptor ) );
|
(void *)&fDeviceDescriptor, sizeof(fDeviceDescriptor));
|
||||||
|
|
||||||
if ( retval != sizeof( m_device_descriptor ) )
|
if (status != sizeof(fDeviceDescriptor)) {
|
||||||
{
|
TRACE(("USB Device: error while getting the device descriptor\n"));
|
||||||
dprintf( "usb Device: error while getting the device descriptor\n" );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintf( "usb Device %d: Vendor id: %d , Product id: %d\n" , devicenum ,
|
TRACE(("USB Device %d: Vendor id: 0x%04x, Product id: 0x%04x, Device version: 0x%04x\n",
|
||||||
m_device_descriptor.vendor_id , m_device_descriptor.product_id );
|
fDeviceAddress, fDeviceDescriptor.vendor_id,
|
||||||
|
fDeviceDescriptor.product_id, fDeviceDescriptor.device_version));
|
||||||
// 4. Get the configurations
|
|
||||||
m_configurations = (usb_configuration_descriptor *)malloc( m_device_descriptor.num_configurations * sizeof (usb_configuration_descriptor) );
|
// Get the configurations
|
||||||
if ( m_configurations == 0 )
|
fConfigurations = (usb_configuration_descriptor *)malloc(fDeviceDescriptor.num_configurations
|
||||||
{
|
* sizeof(usb_configuration_descriptor));
|
||||||
dprintf( "usb Device: out of memory during config creations!\n" );
|
if (fConfigurations == NULL) {
|
||||||
|
TRACE(("USB Device: out of memory during config creations!\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( int i = 0 ; i < m_device_descriptor.num_configurations ; i++ )
|
for (int32 i = 0; i < fDeviceDescriptor.num_configurations; i++) {
|
||||||
{
|
size_t size = GetDescriptor(USB_DESCRIPTOR_CONFIGURATION, i,
|
||||||
if ( GetDescriptor( USB_DESCRIPTOR_CONFIGURATION , i ,
|
(void *)&fConfigurations[i], sizeof(usb_configuration_descriptor));
|
||||||
(void *)( m_configurations + i ) , sizeof (usb_configuration_descriptor ) ) != sizeof( usb_configuration_descriptor ) )
|
|
||||||
{
|
if (size != sizeof(usb_configuration_descriptor)) {
|
||||||
dprintf( "usb Device %d: error fetching configuration %d ...\n" , m_devicenum , i );
|
TRACE(("USB Device %d: error fetching configuration %d\n", fDeviceAddress, i));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Set the default configuration
|
// Set default configuration
|
||||||
dprintf( "usb Device %d: setting configuration %d\n" , m_devicenum , 0 );
|
TRACE(("USB Device %d: setting default configuration\n", fDeviceAddress));
|
||||||
SetConfiguration( 0 );
|
SetConfiguration(0);
|
||||||
|
|
||||||
//6. TODO: Find drivers for the device
|
// ToDo: Find drivers for the device
|
||||||
|
fInitOK = true;
|
||||||
m_initok = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Returns the length that was copied (index gives the number of the config)
|
|
||||||
int16 Device::GetDescriptor( uint8 descriptor_type , uint16 index ,
|
|
||||||
void *buffer , size_t size )
|
|
||||||
{
|
|
||||||
size_t actual_length = 0;
|
|
||||||
m_defaultPipe->SendRequest(USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD , //Type
|
|
||||||
USB_REQUEST_GET_DESCRIPTOR , //Request
|
|
||||||
( descriptor_type << 8 ) | index , //Value
|
|
||||||
0 , //Index
|
|
||||||
size , //Length
|
|
||||||
buffer , //Buffer
|
|
||||||
size , //Bufferlength
|
|
||||||
&actual_length ); //length
|
|
||||||
return actual_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t Device::SetConfiguration( uint8 value )
|
|
||||||
{
|
|
||||||
if ( value >= m_device_descriptor.num_configurations )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
m_defaultPipe->SendRequest( USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD , //Type
|
|
||||||
USB_REQUEST_SET_CONFIGURATION , //Request
|
|
||||||
value , //Value
|
|
||||||
0 , //Index
|
|
||||||
0 , //Length
|
|
||||||
NULL , //Buffer
|
|
||||||
0 , //Bufferlength
|
|
||||||
0 ); //length
|
|
||||||
|
|
||||||
//Set current configuration
|
status_t
|
||||||
m_current_configuration = m_configurations + value;
|
Device::InitCheck()
|
||||||
|
{
|
||||||
|
if (fInitOK)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Returns the length that was copied (index gives the number of the config)
|
||||||
|
size_t
|
||||||
|
Device::GetDescriptor(uint8 descriptorType, uint16 index, void *buffer,
|
||||||
|
size_t bufferSize)
|
||||||
|
{
|
||||||
|
size_t actualLength = 0;
|
||||||
|
fDefaultPipe->SendRequest(
|
||||||
|
USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD, // type
|
||||||
|
USB_REQUEST_GET_DESCRIPTOR, // request
|
||||||
|
(descriptorType << 8) | index, // value
|
||||||
|
0, // index
|
||||||
|
bufferSize, // length
|
||||||
|
buffer, // buffer
|
||||||
|
bufferSize, // buffer length
|
||||||
|
&actualLength); // actual length
|
||||||
|
|
||||||
|
return actualLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Device::SetConfiguration(uint8 value)
|
||||||
|
{
|
||||||
|
if (value >= fDeviceDescriptor.num_configurations)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
status_t result = fDefaultPipe->SendRequest(
|
||||||
|
USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD, // type
|
||||||
|
USB_REQUEST_SET_CONFIGURATION, // request
|
||||||
|
value, // value
|
||||||
|
0, // index
|
||||||
|
0, // length
|
||||||
|
NULL, // buffer
|
||||||
|
0, // buffer length
|
||||||
|
NULL); // actual length
|
||||||
|
|
||||||
|
if (result < B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
// Set current configuration
|
||||||
|
fCurrentConfiguration = &fConfigurations[value];
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,192 +1,174 @@
|
|||||||
//------------------------------------------------------------------------------
|
/*
|
||||||
// Copyright (c) 2003-2004, Niels S. Reedijk
|
* Copyright 2003-2006, Haiku Inc. All rights reserved.
|
||||||
//
|
* Distributed under the terms of the MIT License.
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
*
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
* Authors:
|
||||||
// to deal in the Software without restriction, including without limitation
|
* Niels S. Reedijk
|
||||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
*/
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
// Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
#include "usb_p.h"
|
#include "usb_p.h"
|
||||||
|
|
||||||
Hub::Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum , bool lowspeed )
|
|
||||||
: Device ( bus , parent , desc , devicenum , lowspeed )
|
|
||||||
{
|
|
||||||
dprintf( "USB Hub is being initialised\n" );
|
|
||||||
size_t actual_length;
|
|
||||||
|
|
||||||
if ( m_initok == false )
|
#define TRACE_HUB
|
||||||
{
|
#ifdef TRACE_HUB
|
||||||
dprintf( "Hub::Hub() Device failed to initialize\n" );
|
#define TRACE(x) dprintf x
|
||||||
|
#else
|
||||||
|
#define TRACE(x) /* nothing */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
Hub::Hub(BusManager *bus, Device *parent, usb_device_descriptor &desc,
|
||||||
|
int8 deviceAddress, bool lowSpeed)
|
||||||
|
: Device(bus, parent, desc, deviceAddress, lowSpeed)
|
||||||
|
{
|
||||||
|
TRACE(("USB Hub is being initialised\n"));
|
||||||
|
|
||||||
|
if (!fInitOK) {
|
||||||
|
TRACE(("USB Hub: Device failed to initialize\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Set to false again for the hub init.
|
// Set to false again for the hub init.
|
||||||
m_initok = false;
|
fInitOK = false;
|
||||||
|
|
||||||
if( m_device_descriptor.device_subclass != 0 || m_device_descriptor.device_protocol != 0 )
|
if (fDeviceDescriptor.device_subclass != 0
|
||||||
{
|
|| fDeviceDescriptor.device_protocol != 0) {
|
||||||
dprintf( "USB Hub: wrong class/subclass/protocol! Bailing out\n" );
|
TRACE(("USB Hub: wrong class/subclass/protocol! Bailing out\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_current_configuration->number_interfaces > 1 )
|
if (fCurrentConfiguration->number_interfaces > 1) {
|
||||||
{
|
TRACE(("USB Hub: too many interfaces\n"));
|
||||||
dprintf( "USB Hub: too much interfaces! Bailing out\n" );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintf( "USB Hub this: %p" , this );
|
size_t actualLength;
|
||||||
|
if (GetDescriptor(USB_DESCRIPTOR_INTERFACE, 0, (void *)&fInterruptInterface,
|
||||||
if ( GetDescriptor( USB_DESCRIPTOR_INTERFACE , 0 ,
|
sizeof(usb_interface_descriptor)) != sizeof(usb_interface_descriptor)) {
|
||||||
(void *)&m_interrupt_interface ,
|
TRACE(("USB Hub: error getting the interrupt interface\n"));
|
||||||
sizeof (usb_interface_descriptor) ) != sizeof( usb_interface_descriptor ) )
|
|
||||||
{
|
|
||||||
dprintf( "USB Hub: error getting the interrupt interface! Bailing out.\n" );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_interrupt_interface.num_endpoints > 1 )
|
if (fInterruptInterface.num_endpoints > 1) {
|
||||||
{
|
TRACE(("USB Hub: too many endpoints\n"));
|
||||||
dprintf( "USB Hub: too much endpoints! Bailing out.\n" );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( GetDescriptor( USB_DESCRIPTOR_ENDPOINT , 0 ,
|
if (GetDescriptor(USB_DESCRIPTOR_ENDPOINT, 0, (void *)&fInterruptEndpoint,
|
||||||
(void *)&m_interrupt_endpoint ,
|
sizeof(usb_endpoint_descriptor)) != sizeof(usb_endpoint_descriptor)) {
|
||||||
sizeof (usb_endpoint_descriptor) ) != sizeof (usb_endpoint_descriptor ) )
|
TRACE(("USB Hub: Error getting the endpoint\n"));
|
||||||
{
|
|
||||||
dprintf( "USB Hub: Error getting the endpoint. Bailing out\n" );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_interrupt_endpoint.attributes != 0x03 ) //interrupt transfer
|
if (fInterruptEndpoint.attributes != 0x03) { // interrupt transfer
|
||||||
{
|
TRACE(("USB Hub: Not an interrupt endpoint\n"));
|
||||||
dprintf( "USB Hub: Not an interrupt endpoint. Bailing out\n" );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintf( "USB Hub: Getting hub descriptor...\n" );
|
TRACE(("USB Hub: Getting hub descriptor...\n"));
|
||||||
if ( GetDescriptor( USB_DESCRIPTOR_HUB , 0 ,
|
if (GetDescriptor(USB_DESCRIPTOR_HUB, 0, (void *)&fHubDescriptor,
|
||||||
(void *)&m_hub_descriptor ,
|
sizeof(usb_hub_descriptor)) != sizeof(usb_hub_descriptor)) {
|
||||||
sizeof (usb_hub_descriptor) ) != sizeof (usb_hub_descriptor ) )
|
TRACE(("USB Hub: Error getting hub descriptor\n"));
|
||||||
{
|
|
||||||
dprintf( "USB Hub: Error getting hub descriptor\n" );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable port power on all ports
|
// Enable port power on all ports
|
||||||
for ( int i = 0 ; i < m_hub_descriptor.bNbrPorts ; i++ )
|
for (int32 i = 0; i < fHubDescriptor.bNbrPorts; i++) {
|
||||||
m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT ,
|
fDefaultPipe->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
|
||||||
USB_REQUEST_SET_FEATURE ,
|
USB_REQUEST_SET_FEATURE,
|
||||||
PORT_POWER ,
|
PORT_POWER,
|
||||||
i + 1 , //index
|
i + 1,
|
||||||
0 ,
|
0,
|
||||||
NULL ,
|
NULL,
|
||||||
0 ,
|
0,
|
||||||
&actual_length );
|
&actualLength);
|
||||||
//Wait for power to stabilize
|
}
|
||||||
snooze( m_hub_descriptor.bPwrOn2PwrGood * 2 );
|
|
||||||
|
// Wait for power to stabilize
|
||||||
//We're basically done now
|
snooze(fHubDescriptor.bPwrOn2PwrGood * 2);
|
||||||
m_initok = true;
|
|
||||||
dprintf( "USB Hub: initialised ok\n" );
|
fInitOK = true;
|
||||||
|
TRACE(("USB Hub: initialised ok\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hub::Explore()
|
|
||||||
|
void
|
||||||
|
Hub::Explore()
|
||||||
{
|
{
|
||||||
size_t actual_length;
|
for (int32 i = 0; i < fHubDescriptor.bNbrPorts; i++) {
|
||||||
|
size_t actualLength;
|
||||||
for ( int i = 0 ; i < m_hub_descriptor.bNbrPorts ; i++ )
|
|
||||||
{
|
|
||||||
// Get the current port status
|
// Get the current port status
|
||||||
m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_IN ,
|
fDefaultPipe->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_IN,
|
||||||
USB_REQUEST_GET_STATUS ,
|
USB_REQUEST_GET_STATUS,
|
||||||
0 , //Value
|
0,
|
||||||
i + 1 , //Index
|
i + 1,
|
||||||
4 , //length
|
4,
|
||||||
(void *)&m_port_status[i],
|
(void *)&fPortStatus[i],
|
||||||
4 ,
|
4,
|
||||||
&actual_length );
|
&actualLength);
|
||||||
if ( actual_length < 4 )
|
|
||||||
{
|
if (actualLength < 4) {
|
||||||
dprintf( "USB Hub: ERROR getting port status\n" );
|
TRACE(("USB Hub: error getting port status\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dprintf("status: 0x%04x; change: 0x%04x\n", m_port_status[i].status, m_port_status[i].change);
|
|
||||||
|
|
||||||
//We need to test the port change against a number of things
|
|
||||||
|
|
||||||
if ( m_port_status[i].status & PORT_RESET )
|
|
||||||
{
|
|
||||||
//We didn't do this!
|
|
||||||
m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT ,
|
|
||||||
USB_REQUEST_CLEAR_FEATURE ,
|
|
||||||
PORT_RESET ,
|
|
||||||
i + 1 , //index
|
|
||||||
0 ,
|
|
||||||
NULL ,
|
|
||||||
0 ,
|
|
||||||
&actual_length );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ( m_port_status[i].change & PORT_STATUS_CONNECTION )
|
|
||||||
{
|
|
||||||
if ( m_port_status[i].status & PORT_STATUS_CONNECTION )
|
|
||||||
{
|
|
||||||
//New device attached!
|
|
||||||
|
|
||||||
if ((m_port_status[i].status & PORT_STATUS_ENABLE) == 0) {
|
//TRACE(("status: 0x%04x; change: 0x%04x\n", fPortStatus[i].status, fPortStatus[i].change));
|
||||||
|
|
||||||
|
// We need to test the port change against a number of things
|
||||||
|
if (fPortStatus[i].status & PORT_RESET) {
|
||||||
|
fDefaultPipe->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
|
||||||
|
USB_REQUEST_CLEAR_FEATURE,
|
||||||
|
PORT_RESET,
|
||||||
|
i + 1,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
&actualLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fPortStatus[i].change & PORT_STATUS_CONNECTION) {
|
||||||
|
if (fPortStatus[i].status & PORT_STATUS_CONNECTION) {
|
||||||
|
// New device attached!
|
||||||
|
|
||||||
|
if ((fPortStatus[i].status & PORT_STATUS_ENABLE) == 0) {
|
||||||
// enable the port if it isn't
|
// enable the port if it isn't
|
||||||
m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT ,
|
fDefaultPipe->SendRequest(
|
||||||
USB_REQUEST_SET_FEATURE ,
|
USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
|
||||||
PORT_ENABLE ,
|
USB_REQUEST_SET_FEATURE,
|
||||||
i + 1 , //index
|
PORT_ENABLE,
|
||||||
0 ,
|
i + 1,
|
||||||
NULL ,
|
0,
|
||||||
0 ,
|
NULL,
|
||||||
&actual_length );
|
0,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintf( "USB Hub Explore(): New device connected\n" );
|
TRACE(("USB Hub: Explore(): New device connected\n"));
|
||||||
Device *newdev;
|
|
||||||
if ( m_port_status[i].status & PORT_STATUS_LOW_SPEED )
|
Device *newDevice;
|
||||||
newdev = m_bus->AllocateNewDevice( this , true );
|
if (fPortStatus[i].status & PORT_STATUS_LOW_SPEED)
|
||||||
|
newDevice = fBus->AllocateNewDevice(this, true);
|
||||||
else
|
else
|
||||||
newdev = m_bus->AllocateNewDevice( this , false );
|
newDevice = fBus->AllocateNewDevice(this, false);
|
||||||
if ( newdev != 0 )
|
|
||||||
m_children[i] = newdev;
|
if (newDevice)
|
||||||
|
fChildren[i] = newDevice;
|
||||||
|
} else {
|
||||||
|
// Device removed...
|
||||||
|
// ToDo: do something
|
||||||
|
TRACE(("USB Hub Explore(): Device removed\n"));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
// Clear status change
|
||||||
//Device removed...
|
fDefaultPipe->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
|
||||||
//DO something
|
USB_REQUEST_CLEAR_FEATURE,
|
||||||
dprintf( "USB Hub Explore(): Device removed\n" );
|
C_PORT_CONNECTION,
|
||||||
|
i + 1,
|
||||||
}
|
0,
|
||||||
|
NULL,
|
||||||
//Clear status
|
0,
|
||||||
m_defaultPipe->SendRequest( USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT ,
|
NULL);
|
||||||
USB_REQUEST_CLEAR_FEATURE ,
|
}
|
||||||
C_PORT_CONNECTION ,
|
}
|
||||||
i + 1 , //index
|
|
||||||
0 ,
|
|
||||||
NULL ,
|
|
||||||
0 ,
|
|
||||||
&actual_length );
|
|
||||||
} // PORT_STATUS_CONNECTION
|
|
||||||
}//for (...)
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ Pipe::Pipe(Device *device, pipeDirection &direction, uint8 &endpointAddress)
|
|||||||
|
|
||||||
fBus = NULL;
|
fBus = NULL;
|
||||||
if (fDevice)
|
if (fDevice)
|
||||||
fBus = fDevice->GetBusManager();
|
fBus = fDevice->Manager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ Pipe::DeviceAddress()
|
|||||||
if (!fDevice)
|
if (!fDevice)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return fDevice->GetAddress();
|
return fDevice->Address();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -42,9 +42,10 @@ Pipe::DeviceAddress()
|
|||||||
|
|
||||||
|
|
||||||
ControlPipe::ControlPipe(Device *device, pipeDirection direction,
|
ControlPipe::ControlPipe(Device *device, pipeDirection direction,
|
||||||
uint8 endpointAddress)
|
pipeSpeed speed, uint8 endpointAddress)
|
||||||
: Pipe(device, direction, endpointAddress)
|
: Pipe(device, direction, endpointAddress)
|
||||||
{
|
{
|
||||||
|
fSpeed = speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -64,7 +65,7 @@ ControlPipe::DeviceAddress()
|
|||||||
if (!fDevice)
|
if (!fDevice)
|
||||||
return fDeviceAddress;
|
return fDeviceAddress;
|
||||||
|
|
||||||
return fDevice->GetAddress();
|
return fDevice->Address();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,284 +1,296 @@
|
|||||||
//------------------------------------------------------------------------------
|
/*
|
||||||
// Copyright (c) 2003-2004, Niels S. Reedijk
|
* Copyright 2003-2006, Haiku Inc. All rights reserved.
|
||||||
//
|
* Distributed under the terms of the MIT License.
|
||||||
// AllocArea implementation (c) 2002 Marcus Overhagen <marcus@overhagen.de>
|
*
|
||||||
//
|
* Authors:
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
* Niels S. Reedijk
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
*/
|
||||||
// to deal in the Software without restriction, including without limitation
|
|
||||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
// Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
#include <module.h>
|
#include <module.h>
|
||||||
#include <util/kernel_cpp.h>
|
#include <util/kernel_cpp.h>
|
||||||
|
|
||||||
#include "usb_p.h"
|
#include "usb_p.h"
|
||||||
|
|
||||||
#define MODULE_NAME "usb stack: "
|
|
||||||
|
#define TRACE_STACK
|
||||||
|
#ifdef TRACE_STACK
|
||||||
|
#define TRACE(x) dprintf x
|
||||||
|
#else
|
||||||
|
#define TRACE(x) /* nothing */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
Stack::Stack()
|
Stack::Stack()
|
||||||
{
|
{
|
||||||
dprintf(MODULE_NAME"stack init\n");
|
TRACE(("usb stack: stack init\n"));
|
||||||
//Init the master lock
|
|
||||||
m_master = create_sem( 1 , "usb master lock" );
|
|
||||||
set_sem_owner( m_master , B_SYSTEM_TEAM );
|
|
||||||
|
|
||||||
//Create the data lock
|
|
||||||
m_datalock = create_sem( 1 , "usb data lock" );
|
|
||||||
set_sem_owner( m_datalock , B_SYSTEM_TEAM );
|
|
||||||
|
|
||||||
//Set the global "data" variable to this
|
// Create the master lock
|
||||||
data = this;
|
fMasterLock = create_sem(1, "usb master lock");
|
||||||
|
set_sem_owner(fMasterLock, B_SYSTEM_TEAM);
|
||||||
|
|
||||||
|
// Create the data lock
|
||||||
|
fDataLock = create_sem(1, "usb data lock");
|
||||||
|
set_sem_owner(fDataLock, B_SYSTEM_TEAM);
|
||||||
|
|
||||||
|
// Set the global "data" variable to this
|
||||||
|
usb_stack = this;
|
||||||
|
|
||||||
|
// Initialise the memory chunks: create 8, 16 and 32 byte-heaps
|
||||||
|
// NOTE: This is probably the most ugly code you will see in the
|
||||||
|
// whole stack. Unfortunately this is needed because of the fact
|
||||||
|
// that the compiler doesn't like us to apply pointer arithmethic
|
||||||
|
// to (void *) pointers.
|
||||||
|
|
||||||
//Initialise the memory chunks: create 8, 16 and 32 byte-heaps
|
|
||||||
//NOTE: This is probably the most ugly code you will see in the
|
|
||||||
//whole stack. Unfortunately this is needed because of the fact
|
|
||||||
//that the compiler doesn't like us to apply pointer arithmethic
|
|
||||||
//to (void *) pointers.
|
|
||||||
|
|
||||||
// 8-byte heap
|
// 8-byte heap
|
||||||
m_areafreecount[0] = 0;
|
fAreaFreeCount[0] = 0;
|
||||||
m_areas[0] = AllocateArea( &m_logical[0] , &m_physical[0] , B_PAGE_SIZE ,
|
fAreas[0] = AllocateArea(&fLogical[0], &fPhysical[0], B_PAGE_SIZE,
|
||||||
"8-byte chunk area" );
|
"8-byte chunk area");
|
||||||
if ( m_areas[0] < B_OK )
|
|
||||||
{
|
if (fAreas[0] < B_OK) {
|
||||||
dprintf(MODULE_NAME"8-byte chunk area failed to initialise\n" );
|
TRACE(("usb stack: 8-byte chunk area failed to initialise\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_8_listhead = (addr_t)m_logical[0];
|
fListhead8 = (addr_t)fLogical[0];
|
||||||
|
for (int32 i = 0; i < B_PAGE_SIZE / 8; i++) {
|
||||||
|
memory_chunk *chunk = (memory_chunk *)((addr_t)fLogical[0] + 8 * i);
|
||||||
|
chunk->physical = (addr_t)fPhysical[0] + 8 * i;
|
||||||
|
|
||||||
for ( int i = 0 ; i < B_PAGE_SIZE/8 ; i++ )
|
if (i < B_PAGE_SIZE / 8 - 1)
|
||||||
{
|
chunk->next_item = (addr_t)fLogical[0] + 8 * (i + 1);
|
||||||
memory_chunk *chunk = (memory_chunk *)((addr_t)m_logical[0] + 8 * i);
|
|
||||||
chunk->physical = (addr_t)m_physical[0] + 8 * i;
|
|
||||||
if ( i != B_PAGE_SIZE / 8 - 1 )
|
|
||||||
chunk->next_item = (addr_t)m_logical[0] + 8 * ( i + 1 );
|
|
||||||
else
|
else
|
||||||
chunk->next_item = NULL;
|
chunk->next_item = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 16-byte heap
|
// 16-byte heap
|
||||||
m_areafreecount[1] = 0;
|
fAreaFreeCount[1] = 0;
|
||||||
m_areas[1] = AllocateArea( &m_logical[1] , &m_physical[1] , B_PAGE_SIZE ,
|
fAreas[1] = AllocateArea(&fLogical[1], &fPhysical[1], B_PAGE_SIZE,
|
||||||
"16-byte chunk area" );
|
"16-byte chunk area");
|
||||||
if ( m_areas[1] < B_OK )
|
|
||||||
{
|
if (fAreas[1] < B_OK) {
|
||||||
dprintf(MODULE_NAME"16-byte chunk area failed to initialise\n" );
|
TRACE(("usb stack: 16-byte chunk area failed to initialise\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_16_listhead = (addr_t)m_logical[1];
|
fListhead16 = (addr_t)fLogical[1];
|
||||||
|
for (int32 i = 0; i < B_PAGE_SIZE / 16; i++) {
|
||||||
|
memory_chunk *chunk = (memory_chunk *)((addr_t)fLogical[1] + 16 * i);
|
||||||
|
chunk->physical = (addr_t)fPhysical[1] + 16 * i;
|
||||||
|
|
||||||
for ( int i = 0 ; i < B_PAGE_SIZE/16 ; i++ )
|
if (i < B_PAGE_SIZE / 16 - 1)
|
||||||
{
|
chunk->next_item = (addr_t)fLogical[1] + 16 * (i + 1);
|
||||||
memory_chunk *chunk = (memory_chunk *)((addr_t)m_logical[1] + 16 * i);
|
|
||||||
chunk->physical = (addr_t)m_physical[1] + 16 * i;
|
|
||||||
if ( i != B_PAGE_SIZE / 16 - 1 )
|
|
||||||
chunk->next_item = (addr_t)m_logical[1] + 16 * ( i + 1 );
|
|
||||||
else
|
else
|
||||||
chunk->next_item = NULL;
|
chunk->next_item = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 32-byte heap
|
// 32-byte heap
|
||||||
m_areafreecount[2] = 0;
|
fAreaFreeCount[2] = 0;
|
||||||
m_areas[2] = AllocateArea( &m_logical[2] , &m_physical[2] , B_PAGE_SIZE ,
|
fAreas[2] = AllocateArea(&fLogical[2], &fPhysical[2], B_PAGE_SIZE,
|
||||||
"32-byte chunk area" );
|
"32-byte chunk area");
|
||||||
if ( m_areas[2] < B_OK )
|
|
||||||
{
|
if (fAreas[2] < B_OK) {
|
||||||
dprintf(MODULE_NAME"32-byte chunk area failed to initialise\n" );
|
TRACE(("usb stack: 32-byte chunk area failed to initialise\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_32_listhead = (addr_t)m_logical[2];
|
fListhead32 = (addr_t)fLogical[2];
|
||||||
|
for (int32 i = 0; i < B_PAGE_SIZE / 32; i++) {
|
||||||
|
memory_chunk *chunk = (memory_chunk *)((addr_t)fLogical[2] + 32 * i);
|
||||||
|
chunk->physical = (addr_t)fPhysical[2] + 32 * i;
|
||||||
|
|
||||||
for ( int i = 0 ; i < B_PAGE_SIZE/32 ; i++ )
|
if (i < B_PAGE_SIZE / 32 - 1)
|
||||||
{
|
chunk->next_item = (addr_t)fLogical[2] + 32 * (i + 1);
|
||||||
memory_chunk *chunk = (memory_chunk *)((addr_t)m_logical[2] + 32 * i);
|
|
||||||
chunk->physical = (addr_t)m_physical[2] + 32 * i;
|
|
||||||
if ( i != B_PAGE_SIZE / 32 - 1 )
|
|
||||||
chunk->next_item = (addr_t)m_logical[2] + 32 * ( i + 1 );
|
|
||||||
else
|
else
|
||||||
chunk->next_item = NULL;
|
chunk->next_item = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check for host controller modules
|
// Check for host controller modules
|
||||||
void *list = open_module_list( "busses/usb" );
|
void *moduleList = open_module_list("busses/usb");
|
||||||
char modulename[B_PATH_NAME_LENGTH];
|
char moduleName[B_PATH_NAME_LENGTH];
|
||||||
size_t buffersize = sizeof(modulename);
|
size_t bufferSize = sizeof(moduleName);
|
||||||
dprintf(MODULE_NAME"Looking for host controller modules\n" );
|
|
||||||
while( read_next_module_name( list , modulename , &buffersize ) == B_OK )
|
TRACE(("usb stack: Looking for host controller modules\n"));
|
||||||
{
|
while(read_next_module_name(moduleList, moduleName, &bufferSize) == B_OK) {
|
||||||
dprintf(MODULE_NAME"Found module %s\n" , modulename );
|
bufferSize = sizeof(moduleName);
|
||||||
buffersize = sizeof(modulename);
|
TRACE(("usb stack: Found module %s\n", moduleName));
|
||||||
host_controller_info *module = 0;
|
|
||||||
if ( get_module( modulename , (module_info **)&module ) != B_OK )
|
host_controller_info *module = NULL;
|
||||||
|
if (get_module(moduleName, (module_info **)&module) != B_OK)
|
||||||
continue;
|
continue;
|
||||||
if ( module->add_to( *this) != B_OK )
|
|
||||||
|
if (module->add_to(*this) != B_OK)
|
||||||
continue;
|
continue;
|
||||||
dprintf(MODULE_NAME"module %s successfully loaded\n" , modulename );
|
|
||||||
|
TRACE(("usb stack: module %s successfully loaded\n", moduleName));
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_busmodules.Count() == 0 )
|
if (fBusManagers.Count() == 0)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Stack::~Stack()
|
Stack::~Stack()
|
||||||
{
|
{
|
||||||
//Release the bus modules
|
//Release the bus modules
|
||||||
for( Vector<BusManager *>::Iterator i = m_busmodules.Begin() ; i != m_busmodules.End() ; i++ )
|
for (Vector<BusManager *>::Iterator i = fBusManagers.Begin();
|
||||||
|
i != fBusManagers.End(); i++) {
|
||||||
delete (*i);
|
delete (*i);
|
||||||
delete_area( m_areas[0] );
|
}
|
||||||
delete_area( m_areas[1] );
|
|
||||||
delete_area( m_areas[2] );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t Stack::InitCheck()
|
delete_area(fAreas[0]);
|
||||||
|
delete_area(fAreas[1]);
|
||||||
|
delete_area(fAreas[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Stack::InitCheck()
|
||||||
{
|
{
|
||||||
if ( m_busmodules.Count() == 0 )
|
if (fBusManagers.Count() == 0)
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stack::Lock()
|
|
||||||
{
|
|
||||||
acquire_sem( m_master );
|
|
||||||
}
|
|
||||||
|
|
||||||
void Stack::Unlock()
|
void
|
||||||
|
Stack::Lock()
|
||||||
{
|
{
|
||||||
release_sem( m_master );
|
acquire_sem(fMasterLock);
|
||||||
}
|
|
||||||
|
|
||||||
void Stack::AddBusManager( BusManager *bus )
|
|
||||||
{
|
|
||||||
m_busmodules.PushBack( bus );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t Stack::AllocateChunk( void **log , void **phy , uint8 size )
|
void
|
||||||
|
Stack::Unlock()
|
||||||
|
{
|
||||||
|
release_sem(fMasterLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Stack::AddBusManager(BusManager *busManager)
|
||||||
|
{
|
||||||
|
fBusManagers.PushBack(busManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Stack::AllocateChunk(void **logicalAddress, void **physicalAddress, uint8 size)
|
||||||
{
|
{
|
||||||
Lock();
|
Lock();
|
||||||
|
|
||||||
addr_t listhead;
|
addr_t listhead;
|
||||||
if ( size <= 8 )
|
if (size <= 8)
|
||||||
listhead = m_8_listhead;
|
listhead = fListhead8;
|
||||||
else if ( size <= 16 )
|
else if (size <= 16)
|
||||||
listhead = m_16_listhead;
|
listhead = fListhead16;
|
||||||
else if ( size <= 32 )
|
else if (size <= 32)
|
||||||
listhead = m_32_listhead;
|
listhead = fListhead32;
|
||||||
else
|
else {
|
||||||
{
|
TRACE(("usb stack: Chunk size %d to big\n", size));
|
||||||
dprintf (MODULE_NAME"Chunk size %i to big\n" , size );
|
|
||||||
Unlock();
|
Unlock();
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( listhead == NULL )
|
if (listhead == NULL) {
|
||||||
{
|
TRACE(("usb stack: Out of memory on this list\n"));
|
||||||
Unlock();
|
Unlock();
|
||||||
dprintf(MODULE_NAME"Out of memory on this list\n" );
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintf(MODULE_NAME"Stack::Allocate() listhead: %ld\n" , listhead );
|
//TRACE(("usb stack: Stack::Allocate() listhead: 0x%08x\n", listhead));
|
||||||
|
|
||||||
memory_chunk *chunk = (memory_chunk *)listhead;
|
memory_chunk *chunk = (memory_chunk *)listhead;
|
||||||
*log = (void *)listhead;
|
*logicalAddress = (void *)listhead;
|
||||||
*phy = (void *)(chunk->physical);
|
*physicalAddress = (void *)chunk->physical;
|
||||||
if ( chunk->next_item == NULL )
|
if (chunk->next_item == NULL) {
|
||||||
//TODO: allocate more memory
|
//TODO: allocate more memory
|
||||||
listhead = NULL;
|
listhead = NULL;
|
||||||
else
|
} else {
|
||||||
listhead = chunk->next_item;
|
listhead = chunk->next_item;
|
||||||
|
}
|
||||||
//Update our listhead pointers
|
|
||||||
if ( size <= 8 )
|
// Update our listhead pointers
|
||||||
m_8_listhead = listhead;
|
if (size <= 8)
|
||||||
else if ( size <= 16 )
|
fListhead8 = listhead;
|
||||||
m_16_listhead = listhead;
|
else if (size <= 16)
|
||||||
else if ( size <= 32 )
|
fListhead16 = listhead;
|
||||||
m_32_listhead = listhead;
|
else if (size <= 32)
|
||||||
|
fListhead32 = listhead;
|
||||||
|
|
||||||
Unlock();
|
Unlock();
|
||||||
dprintf(MODULE_NAME"allocated a new chunk with size %u\n" , size );
|
//TRACE(("usb stack: allocated a new chunk with size %u\n", size));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t Stack::FreeChunk( void *log , void *phy , uint8 size )
|
|
||||||
|
status_t
|
||||||
|
Stack::FreeChunk(void *logicalAddress, void *physicalAddress, uint8 size)
|
||||||
{
|
{
|
||||||
Lock();
|
Lock();
|
||||||
|
|
||||||
addr_t listhead;
|
addr_t listhead;
|
||||||
if ( size <= 8 )
|
if (size <= 8)
|
||||||
listhead = m_8_listhead;
|
listhead = fListhead8;
|
||||||
else if ( size <= 16 )
|
else if (size <= 16)
|
||||||
listhead = m_16_listhead;
|
listhead = fListhead16;
|
||||||
else if ( size <= 32 )
|
else if (size <= 32)
|
||||||
listhead = m_32_listhead;
|
listhead = fListhead32;
|
||||||
else
|
else {
|
||||||
{
|
TRACE(("usb stack: Chunk size %d invalid\n", size));
|
||||||
dprintf (MODULE_NAME"Chunk size %i invalid\n" , size );
|
|
||||||
Unlock();
|
Unlock();
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_chunk *chunk = (memory_chunk *)log;
|
memory_chunk *chunk = (memory_chunk *)logicalAddress;
|
||||||
|
|
||||||
chunk->next_item = listhead;
|
chunk->next_item = listhead;
|
||||||
chunk->physical = (addr_t)phy;
|
chunk->physical = (addr_t)physicalAddress;
|
||||||
|
|
||||||
if ( size <= 8 )
|
if (size <= 8)
|
||||||
m_8_listhead = (addr_t)log;
|
fListhead8 = (addr_t)logicalAddress;
|
||||||
else if ( size <= 16 )
|
else if (size <= 16)
|
||||||
m_16_listhead = (addr_t)log;
|
fListhead16 = (addr_t)logicalAddress;
|
||||||
else if ( size <= 32 )
|
else if (size <= 32)
|
||||||
m_32_listhead = (addr_t)log;
|
fListhead32 = (addr_t)logicalAddress;
|
||||||
|
|
||||||
Unlock();
|
Unlock();
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
area_id Stack::AllocateArea( void **log , void **phy , size_t size , const char *name )
|
|
||||||
{
|
|
||||||
physical_entry pe;
|
|
||||||
void * logadr;
|
|
||||||
area_id areaid;
|
|
||||||
status_t rv;
|
|
||||||
|
|
||||||
dprintf(MODULE_NAME"allocating %ld bytes for %s\n",size,name);
|
|
||||||
|
|
||||||
|
area_id
|
||||||
|
Stack::AllocateArea(void **logicalAddress, void **physicalAddress, size_t size,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
TRACE(("usb stack: allocating %ld bytes for %s\n", size, name));
|
||||||
|
|
||||||
|
void *logAddress;
|
||||||
size = (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
|
size = (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
|
||||||
areaid = create_area(name, &logadr, B_ANY_KERNEL_ADDRESS,size,B_FULL_LOCK | B_CONTIGUOUS, 0 );
|
area_id area = create_area(name, &logAddress, B_ANY_KERNEL_ADDRESS, size,
|
||||||
if (areaid < B_OK) {
|
B_FULL_LOCK | B_CONTIGUOUS, 0);
|
||||||
dprintf(MODULE_NAME"couldn't allocate area %s\n",name);
|
|
||||||
|
if (area < B_OK) {
|
||||||
|
TRACE(("usb stack: couldn't allocate area %s\n", name));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
rv = get_memory_map(logadr,size,&pe,1);
|
|
||||||
if (rv < B_OK) {
|
physical_entry physicalEntry;
|
||||||
delete_area(areaid);
|
status_t result = get_memory_map(logAddress, size, &physicalEntry, 1);
|
||||||
dprintf(MODULE_NAME"couldn't map %s\n",name);
|
if (result < B_OK) {
|
||||||
|
delete_area(area);
|
||||||
|
TRACE(("usb stack: couldn't map area %s\n", name));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
memset(logadr,0,size);
|
|
||||||
if (log)
|
memset(logAddress, 0, size);
|
||||||
*log = logadr;
|
if (logicalAddress)
|
||||||
if (phy)
|
*logicalAddress = logAddress;
|
||||||
*phy = pe.address;
|
|
||||||
dprintf(MODULE_NAME"area = %ld, size = %ld, log = 0x%08x, phy = 0x%08x\n",areaid,size,(uint32)logadr,(uint32)(pe.address));
|
if (physicalAddress)
|
||||||
return areaid;
|
*physicalAddress = physicalEntry.address;
|
||||||
|
|
||||||
|
TRACE(("usb stack: area = 0x%08x, size = %ld, log = 0x%08x, phy = 0x%08x\n",
|
||||||
|
area, size, logAddress, physicalEntry.address));
|
||||||
|
return area;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack *data = 0;
|
|
||||||
|
Stack *usb_stack = NULL;
|
||||||
|
@ -1,95 +1,101 @@
|
|||||||
//------------------------------------------------------------------------------
|
/*
|
||||||
// Copyright (c) 2003-2004, Niels S. Reedijk
|
* Copyright 2003-2006, Haiku Inc. All rights reserved.
|
||||||
//
|
* Distributed under the terms of the MIT License.
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
*
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
* Authors:
|
||||||
// to deal in the Software without restriction, including without limitation
|
* Niels S. Reedijk
|
||||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
*/
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
// Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
#include "usb_p.h"
|
#include "usb_p.h"
|
||||||
|
|
||||||
Transfer::Transfer( Pipe *pipe , bool synchronous )
|
|
||||||
|
Transfer::Transfer(Pipe *pipe, bool synchronous)
|
||||||
{
|
{
|
||||||
m_pipe = pipe;
|
fPipe = pipe;
|
||||||
m_buffer = 0;
|
fBuffer = NULL;
|
||||||
m_bufferlength = 0;
|
fBufferLength = 0;
|
||||||
m_actual_length = 0;
|
fActualLength = NULL;
|
||||||
m_timeout = 0;
|
fTimeout = 0;
|
||||||
m_status = 0;
|
fStatus = B_ERROR;
|
||||||
m_sem = B_ERROR;
|
fSem = -1;
|
||||||
m_hcpriv = 0;
|
fHostPrivate = NULL;
|
||||||
|
|
||||||
if ( synchronous == true )
|
if (synchronous) {
|
||||||
{
|
fSem = create_sem(0, "USB Transfer");
|
||||||
m_sem = create_sem( 0 , "USB Transfer" );
|
set_sem_owner(fSem, B_SYSTEM_TEAM);
|
||||||
set_sem_owner ( m_sem , B_SYSTEM_TEAM );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Transfer::~Transfer()
|
Transfer::~Transfer()
|
||||||
{
|
{
|
||||||
if ( m_sem > B_OK )
|
if (fSem >= B_OK)
|
||||||
delete_sem( m_sem );
|
delete_sem(fSem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transfer::SetRequestData( usb_request_data *data )
|
|
||||||
|
void
|
||||||
|
Transfer::SetRequestData(usb_request_data *data)
|
||||||
{
|
{
|
||||||
m_request = data;
|
fRequest = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transfer::SetBuffer( uint8 *buffer )
|
|
||||||
|
void
|
||||||
|
Transfer::SetBuffer(uint8 *buffer)
|
||||||
{
|
{
|
||||||
m_buffer = buffer;
|
fBuffer = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transfer::SetBufferLength( size_t length )
|
|
||||||
|
void
|
||||||
|
Transfer::SetBufferLength(size_t length)
|
||||||
{
|
{
|
||||||
m_bufferlength = length;
|
fBufferLength = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transfer::SetActualLength( size_t *actual_length )
|
|
||||||
{
|
|
||||||
m_actual_length = actual_length;
|
|
||||||
};
|
|
||||||
|
|
||||||
void Transfer::SetCallbackFunction( usb_callback_func callback )
|
void
|
||||||
|
Transfer::SetActualLength(size_t *actualLength)
|
||||||
{
|
{
|
||||||
m_callback = callback;
|
fActualLength = actualLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transfer::SetHostPrivate( hostcontroller_priv *priv )
|
|
||||||
|
void
|
||||||
|
Transfer::SetCallbackFunction(usb_callback_func callback)
|
||||||
{
|
{
|
||||||
m_hcpriv = priv;
|
fCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transfer::WaitForFinish()
|
|
||||||
{
|
|
||||||
if ( m_sem > B_OK )
|
|
||||||
acquire_sem( m_sem );
|
|
||||||
}
|
|
||||||
|
|
||||||
void Transfer::TransferDone()
|
void
|
||||||
|
Transfer::SetHostPrivate(hostcontroller_priv *priv)
|
||||||
{
|
{
|
||||||
if ( m_sem > B_OK )
|
fHostPrivate = priv;
|
||||||
release_sem( m_sem );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Transfer::WaitForFinish()
|
||||||
|
{
|
||||||
|
if (fSem > B_OK)
|
||||||
|
acquire_sem(fSem);
|
||||||
|
// ToDo: and otherwise?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Transfer::TransferDone()
|
||||||
|
{
|
||||||
|
if (fSem > B_OK)
|
||||||
|
release_sem(fSem);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Transfer::Finish()
|
void Transfer::Finish()
|
||||||
{
|
{
|
||||||
//If we are synchronous, release a sem
|
// If we are synchronous, release a sem
|
||||||
if ( m_sem > B_OK )
|
if (fSem > B_OK)
|
||||||
release_sem( m_sem );
|
release_sem(fSem);
|
||||||
}
|
}
|
||||||
|
@ -1,109 +1,95 @@
|
|||||||
//------------------------------------------------------------------------------
|
/*
|
||||||
// Copyright (c) 2003-2004, Niels S. Reedijk
|
* Copyright 2003-2006, Haiku Inc. All rights reserved.
|
||||||
//
|
* Distributed under the terms of the MIT License.
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
*
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
* Authors:
|
||||||
// to deal in the Software without restriction, including without limitation
|
* Niels S. Reedijk
|
||||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
*/
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
// Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
#include <USB.h>
|
#include <USB.h>
|
||||||
#include <util/kernel_cpp.h>
|
#include <util/kernel_cpp.h>
|
||||||
|
|
||||||
#include "usb_p.h"
|
#include "usb_p.h"
|
||||||
|
|
||||||
#define USB_DEBUG
|
|
||||||
#ifdef USB_DEBUG
|
#define TRACE_USB
|
||||||
#define TRACE dprintf
|
#ifdef TRACE_USB
|
||||||
|
#define TRACE(x) dprintf x
|
||||||
#else
|
#else
|
||||||
#define TRACE silent
|
#define TRACE(x) /* nothing */
|
||||||
void silent( const char * , ... ) {}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ++++++++++
|
|
||||||
Loading/unloading the module
|
|
||||||
++++++++++ */
|
|
||||||
|
|
||||||
static int32
|
static int32
|
||||||
bus_std_ops(int32 op, ...)
|
bus_std_ops(int32 op, ...)
|
||||||
{
|
{
|
||||||
Stack *stack;
|
switch (op) {
|
||||||
switch(op) {
|
case B_MODULE_INIT: {
|
||||||
case B_MODULE_INIT:
|
#ifdef TRACE_USB
|
||||||
#ifdef USB_DEBUG
|
set_dprintf_enabled(true);
|
||||||
set_dprintf_enabled( true );
|
load_driver_symbols("usb");
|
||||||
load_driver_symbols( "usb" );
|
#endif
|
||||||
#endif
|
|
||||||
TRACE(("usb_nielx: bus module: init\n"));
|
TRACE(("usb_nielx: bus module: init\n"));
|
||||||
stack = new Stack();
|
|
||||||
if( stack->InitCheck() != B_OK )
|
Stack *stack = new Stack();
|
||||||
{
|
if (stack->InitCheck() != B_OK) {
|
||||||
delete stack;
|
delete stack;
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case B_MODULE_UNINIT:
|
case B_MODULE_UNINIT:
|
||||||
TRACE(("usb_nielx: bus module: uninit\n"));
|
TRACE(("usb_nielx: bus module: uninit\n"));
|
||||||
delete data;
|
delete usb_stack;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ++++++++++
|
/*
|
||||||
This module exports the USB API
|
This module exports the USB API
|
||||||
++++++++++ */
|
*/
|
||||||
|
struct usb_module_info gModuleInfo = {
|
||||||
struct usb_module_info m_module_info =
|
|
||||||
{
|
|
||||||
// First the bus_manager_info:
|
// First the bus_manager_info:
|
||||||
{
|
{
|
||||||
//module_info
|
|
||||||
{
|
{
|
||||||
"bus_managers/usb/nielx" ,
|
"bus_managers/usb/nielx",
|
||||||
B_KEEP_LOADED , // Keep loaded, even if no driver requires it
|
B_KEEP_LOADED, // Keep loaded, even if no driver requires it
|
||||||
bus_std_ops
|
bus_std_ops
|
||||||
} ,
|
},
|
||||||
NULL // the rescan function
|
NULL // the rescan function
|
||||||
} ,
|
},
|
||||||
NULL , // register_driver
|
|
||||||
NULL , // install_notify
|
NULL, // register_driver
|
||||||
NULL , // uninstall_notify
|
NULL, // install_notify
|
||||||
NULL , // get_device_descriptor
|
NULL, // uninstall_notify
|
||||||
NULL , // get_nth_configuration_info
|
NULL, // get_device_descriptor
|
||||||
NULL , // get_configuration
|
NULL, // get_nth_configuration_info
|
||||||
NULL , // set_configuration
|
NULL, // get_configuration
|
||||||
NULL , // set_alt_interface
|
NULL, // set_configuration
|
||||||
NULL , // set_feature
|
NULL, // set_alt_interface
|
||||||
NULL , // clear_feature
|
NULL, // set_feature
|
||||||
NULL , // get_status
|
NULL, // clear_feature
|
||||||
NULL , // get_descriptor
|
NULL, // get_status
|
||||||
NULL , // send_request
|
NULL, // get_descriptor
|
||||||
NULL , // queue_interrupt
|
NULL, // send_request
|
||||||
NULL , // queue_bulk
|
NULL, // queue_interrupt
|
||||||
NULL , // queue_isochronous
|
NULL, // queue_bulk
|
||||||
NULL , // queue_request
|
NULL, // queue_isochronous
|
||||||
NULL , // set_pipe_policy
|
NULL, // queue_request
|
||||||
NULL , // cancel_queued_transfers
|
NULL, // set_pipe_policy
|
||||||
|
NULL, // cancel_queued_transfers
|
||||||
NULL // usb_ioctl
|
NULL // usb_ioctl
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
module_info *modules[] = {
|
module_info *modules[] = {
|
||||||
(module_info *)&m_module_info ,
|
(module_info *)&gModuleInfo,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
@ -1,128 +1,126 @@
|
|||||||
//------------------------------------------------------------------------------
|
/*
|
||||||
// Copyright (c) 2003-2004, Niels S. Reedijk
|
* Copyright 2003-2006, Haiku Inc. All rights reserved.
|
||||||
//
|
* Distributed under the terms of the MIT License.
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
*
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
* Authors:
|
||||||
// to deal in the Software without restriction, including without limitation
|
* Niels S. Reedijk
|
||||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
*/
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
// Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
#ifndef USB_P
|
#ifndef _USB_P_
|
||||||
#define USB_P
|
#define _USB_P_
|
||||||
|
|
||||||
#include "usbspec_p.h"
|
#include "usbspec_p.h"
|
||||||
|
|
||||||
/* ++++++++++
|
|
||||||
Forward declarations
|
|
||||||
++++++++++ */
|
|
||||||
class Stack;
|
class Stack;
|
||||||
class Device;
|
class Device;
|
||||||
class Transfer;
|
class Transfer;
|
||||||
class BusManager;
|
class BusManager;
|
||||||
class ControlPipe;
|
class ControlPipe;
|
||||||
|
|
||||||
/* ++++++++++
|
|
||||||
The host_controller_info
|
struct host_controller_info {
|
||||||
++++++++++ */
|
module_info info;
|
||||||
struct host_controller_info
|
status_t (*control)(uint32 op, void *data, size_t length);
|
||||||
{
|
bool (*add_to)(Stack &stack);
|
||||||
module_info info;
|
|
||||||
status_t (*control)(uint32 op, void *data, size_t length);
|
|
||||||
bool (*add_to)(Stack &stack);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ++++++++++
|
class Stack {
|
||||||
Internal classes
|
|
||||||
++++++++++ */
|
|
||||||
|
|
||||||
class Stack
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Stack();
|
Stack();
|
||||||
~Stack();
|
~Stack();
|
||||||
status_t InitCheck();
|
|
||||||
|
status_t InitCheck();
|
||||||
void Lock();
|
|
||||||
void Unlock();
|
void Lock();
|
||||||
|
void Unlock();
|
||||||
void AddBusManager( BusManager *bus );
|
|
||||||
|
void AddBusManager(BusManager *bus);
|
||||||
status_t AllocateChunk( void **log , void **phy , uint8 size );
|
|
||||||
status_t FreeChunk( void *log , void *phy , uint8 size );
|
status_t AllocateChunk(void **logicalAddress,
|
||||||
area_id AllocateArea( void **log , void **phy , size_t size , const char *name );
|
void **physicalAddress, uint8 size);
|
||||||
|
status_t FreeChunk(void *logicalAddress,
|
||||||
|
void *physicalAddress, uint8 size);
|
||||||
|
|
||||||
|
area_id AllocateArea(void **logicalAddress,
|
||||||
|
void **physicalAddress,
|
||||||
|
size_t size, const char *name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector<BusManager *> m_busmodules;//Stores all the bus modules
|
Vector<BusManager *> fBusManagers;
|
||||||
sem_id m_master; //The master lock
|
|
||||||
sem_id m_datalock; //Lock that controls data transfers
|
sem_id fMasterLock;
|
||||||
area_id m_areas[USB_MAX_AREAS]; //Stores the area_id for the memory pool
|
sem_id fDataLock;
|
||||||
void *m_logical[USB_MAX_AREAS];//Stores the logical base addresses
|
|
||||||
void *m_physical[USB_MAX_AREAS];//Stores the physical base addresses
|
area_id fAreas[USB_MAX_AREAS];
|
||||||
uint16 m_areafreecount[USB_MAX_AREAS]; //Keeps track of how many free chunks there are
|
void *fLogical[USB_MAX_AREAS];
|
||||||
addr_t m_8_listhead;
|
void *fPhysical[USB_MAX_AREAS];
|
||||||
addr_t m_16_listhead;
|
uint16 fAreaFreeCount[USB_MAX_AREAS];
|
||||||
addr_t m_32_listhead;
|
|
||||||
|
addr_t fListhead8;
|
||||||
|
addr_t fListhead16;
|
||||||
|
addr_t fListhead32;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" Stack *data;
|
extern "C" Stack *usb_stack;
|
||||||
|
|
||||||
class Device
|
class Device {
|
||||||
{
|
|
||||||
friend class Pipe;
|
|
||||||
public:
|
public:
|
||||||
Device( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum , bool speed);
|
Device(BusManager *bus, Device *parent,
|
||||||
virtual bool IsHub() { return false; };
|
usb_device_descriptor &desc,
|
||||||
status_t InitCheck();
|
int8 deviceAddress, bool lowSpeed);
|
||||||
|
|
||||||
uint8 GetAddress() { return m_devicenum; };
|
status_t InitCheck();
|
||||||
int16 GetDescriptor( uint8 descriptor_type , uint16 index , void *buffer ,
|
|
||||||
size_t size );
|
virtual bool IsHub() { return false; };
|
||||||
BusManager *GetBusManager() { return m_bus; };
|
int8 Address() { return fDeviceAddress; };
|
||||||
status_t SetConfiguration( uint8 value );
|
BusManager *Manager() { return fBus; };
|
||||||
|
|
||||||
|
size_t GetDescriptor(uint8 descriptorType,
|
||||||
|
uint16 index, void *buffer,
|
||||||
|
size_t bufferSize);
|
||||||
|
|
||||||
|
status_t SetConfiguration(uint8 value);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
usb_device_descriptor m_device_descriptor;
|
friend class Pipe;
|
||||||
usb_configuration_descriptor * m_configurations;
|
|
||||||
usb_configuration_descriptor * m_current_configuration;
|
usb_device_descriptor fDeviceDescriptor;
|
||||||
ControlPipe * m_defaultPipe;
|
usb_configuration_descriptor *fConfigurations;
|
||||||
bool m_initok;
|
usb_configuration_descriptor *fCurrentConfiguration;
|
||||||
bool m_lowspeed;
|
ControlPipe *fDefaultPipe;
|
||||||
BusManager * m_bus;
|
bool fInitOK;
|
||||||
Device * m_parent;
|
bool fLowSpeed;
|
||||||
int8 m_devicenum;
|
BusManager *fBus;
|
||||||
uint8 m_maxpacketin[16]; //Max. size of input
|
Device *fParent;
|
||||||
uint8 m_maxpacketout[16]; //Max size of output
|
int8 fDeviceAddress;
|
||||||
sem_id m_lock;
|
uint8 fMaxPacketIn[16];
|
||||||
|
uint8 fMaxPacketOut[16];
|
||||||
|
sem_id fLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Hub : public Device
|
|
||||||
{
|
class Hub : public Device {
|
||||||
public:
|
public:
|
||||||
Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum , bool lowspeed );
|
Hub(BusManager *bus, Device *parent,
|
||||||
virtual bool IsHub() { return true; };
|
usb_device_descriptor &desc,
|
||||||
|
int8 deviceAddress, bool lowSpeed);
|
||||||
|
|
||||||
void Explore();
|
virtual bool IsHub() { return true; };
|
||||||
private:
|
|
||||||
usb_interface_descriptor m_interrupt_interface;
|
void Explore();
|
||||||
usb_endpoint_descriptor m_interrupt_endpoint;
|
|
||||||
usb_hub_descriptor m_hub_descriptor;
|
private:
|
||||||
|
usb_interface_descriptor fInterruptInterface;
|
||||||
usb_port_status m_port_status[8]; //Max of 8 ports, for the moment
|
usb_endpoint_descriptor fInterruptEndpoint;
|
||||||
Device *m_children[8];
|
usb_hub_descriptor fHubDescriptor;
|
||||||
|
|
||||||
|
usb_port_status fPortStatus[8];
|
||||||
|
Device *fChildren[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This class manages a bus. It is created by the Stack object
|
* This class manages a bus. It is created by the Stack object
|
||||||
* after a host controller gives positive feedback on whether the hardware
|
* after a host controller gives positive feedback on whether the hardware
|
||||||
@ -171,7 +169,6 @@ static int32 ExploreThread(void *data);
|
|||||||
* The Pipe class is the communication management between the hardware and\
|
* The Pipe class is the communication management between the hardware and\
|
||||||
* the stack. It creates packets, manages these and performs callbacks.
|
* the stack. It creates packets, manages these and performs callbacks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Pipe {
|
class Pipe {
|
||||||
public:
|
public:
|
||||||
enum pipeDirection { In, Out, Default };
|
enum pipeDirection { In, Out, Default };
|
||||||
@ -203,6 +200,7 @@ class ControlPipe : public Pipe {
|
|||||||
public:
|
public:
|
||||||
ControlPipe(Device *device,
|
ControlPipe(Device *device,
|
||||||
pipeDirection direction,
|
pipeDirection direction,
|
||||||
|
pipeSpeed speed,
|
||||||
uint8 endpointAddress);
|
uint8 endpointAddress);
|
||||||
|
|
||||||
// Constructor for default control pipe
|
// Constructor for default control pipe
|
||||||
@ -232,11 +230,11 @@ private:
|
|||||||
pipeSpeed fSpeed;
|
pipeSpeed fSpeed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a forward definition of a struct that is defined in the individual
|
* This is a forward definition of a struct that is defined in the individual
|
||||||
* host controller modules
|
* host controller modules
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct hostcontroller_priv;
|
struct hostcontroller_priv;
|
||||||
|
|
||||||
|
|
||||||
@ -245,46 +243,49 @@ struct hostcontroller_priv;
|
|||||||
* packets. The class is only used in the bus_manager: the host controllers
|
* packets. The class is only used in the bus_manager: the host controllers
|
||||||
* receive the internal data structures.
|
* receive the internal data structures.
|
||||||
*/
|
*/
|
||||||
|
class Transfer {
|
||||||
class Transfer
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Transfer( Pipe *pipe , bool synchronous );
|
Transfer(Pipe *pipe, bool synchronous);
|
||||||
~Transfer();
|
~Transfer();
|
||||||
void SetRequestData( usb_request_data *data );
|
|
||||||
void SetBuffer( uint8 *buffer );
|
|
||||||
void SetBufferLength( size_t length );
|
|
||||||
void SetActualLength( size_t * );
|
|
||||||
void SetCallbackFunction( usb_callback_func callback );
|
|
||||||
|
|
||||||
void SetHostPrivate( hostcontroller_priv *priv );
|
|
||||||
|
|
||||||
void WaitForFinish();
|
|
||||||
void TransferDone();
|
|
||||||
void Finish();
|
|
||||||
|
|
||||||
Pipe *GetPipe() { return m_pipe; };
|
|
||||||
uint8 *GetBuffer() { return m_buffer; };
|
|
||||||
size_t GetBufferLength() { return m_bufferlength; };
|
|
||||||
size_t *GetActualLength() { return m_actual_length; };
|
|
||||||
usb_request_data *GetRequestData() { return m_request; };
|
|
||||||
hostcontroller_priv *GetHostPrivate() { return m_hcpriv; };
|
|
||||||
private:
|
|
||||||
//Data that is related to the transfer
|
|
||||||
Pipe *m_pipe;
|
|
||||||
uint8 *m_buffer;
|
|
||||||
size_t m_bufferlength;
|
|
||||||
size_t *m_actual_length;
|
|
||||||
bigtime_t m_timeout;
|
|
||||||
status_t m_status;
|
|
||||||
|
|
||||||
usb_callback_func m_callback;
|
|
||||||
sem_id m_sem;
|
|
||||||
hostcontroller_priv *m_hcpriv;
|
|
||||||
|
|
||||||
//For control transfers
|
Pipe *TransferPipe() { return fPipe; };
|
||||||
usb_request_data *m_request;
|
|
||||||
|
void SetRequestData(usb_request_data *data);
|
||||||
|
usb_request_data *RequestData() { return fRequest; };
|
||||||
|
|
||||||
|
void SetBuffer(uint8 *buffer);
|
||||||
|
uint8 *Buffer() { return fBuffer; };
|
||||||
|
|
||||||
|
void SetBufferLength(size_t length);
|
||||||
|
size_t BufferLength() { return fBufferLength; };
|
||||||
|
|
||||||
|
void SetActualLength(size_t *actualLength);
|
||||||
|
size_t *ActualLength() { return fActualLength; };
|
||||||
|
|
||||||
|
void SetHostPrivate(hostcontroller_priv *priv);
|
||||||
|
hostcontroller_priv *HostPrivate() { return fHostPrivate; };
|
||||||
|
|
||||||
|
void SetCallbackFunction(usb_callback_func callback);
|
||||||
|
|
||||||
|
void WaitForFinish();
|
||||||
|
void TransferDone();
|
||||||
|
void Finish();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Data that is related to the transfer
|
||||||
|
Pipe *fPipe;
|
||||||
|
uint8 *fBuffer;
|
||||||
|
size_t fBufferLength;
|
||||||
|
size_t *fActualLength;
|
||||||
|
bigtime_t fTimeout;
|
||||||
|
status_t fStatus;
|
||||||
|
|
||||||
|
usb_callback_func fCallback;
|
||||||
|
sem_id fSem;
|
||||||
|
hostcontroller_priv *fHostPrivate;
|
||||||
|
|
||||||
|
// For control transfers
|
||||||
|
usb_request_data *fRequest;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,26 +1,13 @@
|
|||||||
//------------------------------------------------------------------------------
|
/*
|
||||||
// Copyright (c) 2003-2005, Niels S. Reedijk
|
* Copyright 2003-2006, Haiku Inc. All rights reserved.
|
||||||
//
|
* Distributed under the terms of the MIT License.
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
*
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
* Authors:
|
||||||
// to deal in the Software without restriction, including without limitation
|
* Niels S. Reedijk
|
||||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
*/
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
// Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
#ifndef USBSPEC_P
|
#ifndef _USBSPEC_P_
|
||||||
#define USBSPEC_P
|
#define _USBSPEC_P_
|
||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <util/Vector.h>
|
#include <util/Vector.h>
|
||||||
@ -28,17 +15,19 @@
|
|||||||
#include <util/kernel_cpp.h>
|
#include <util/kernel_cpp.h>
|
||||||
|
|
||||||
#define USB_MAX_AREAS 8
|
#define USB_MAX_AREAS 8
|
||||||
|
#define POWER_DELAY
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Important data from the USB spec (not interesting for drivers)
|
||||||
|
*/
|
||||||
|
|
||||||
struct memory_chunk
|
struct memory_chunk
|
||||||
{
|
{
|
||||||
addr_t next_item;
|
addr_t next_item;
|
||||||
addr_t physical;
|
addr_t physical;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ++++++++++
|
|
||||||
Important data from the USB spec (not interesting for drivers)
|
|
||||||
++++++++++ */
|
|
||||||
|
|
||||||
#define POWER_DELAY
|
|
||||||
|
|
||||||
struct usb_request_data
|
struct usb_request_data
|
||||||
{
|
{
|
||||||
@ -49,6 +38,7 @@ struct usb_request_data
|
|||||||
uint16 Length;
|
uint16 Length;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct usb_hub_descriptor
|
struct usb_hub_descriptor
|
||||||
{
|
{
|
||||||
uint8 bDescLength;
|
uint8 bDescLength;
|
||||||
@ -63,6 +53,7 @@ struct usb_hub_descriptor
|
|||||||
|
|
||||||
#define USB_DESCRIPTOR_HUB 0x29
|
#define USB_DESCRIPTOR_HUB 0x29
|
||||||
|
|
||||||
|
|
||||||
// USB Spec 1.1 page 273
|
// USB Spec 1.1 page 273
|
||||||
struct usb_port_status
|
struct usb_port_status
|
||||||
{
|
{
|
||||||
@ -70,29 +61,31 @@ struct usb_port_status
|
|||||||
uint16 change;
|
uint16 change;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//The bits in the usb_port_status struct
|
//The bits in the usb_port_status struct
|
||||||
// USB 1.1 spec page 274
|
// USB 1.1 spec page 274
|
||||||
#define PORT_STATUS_CONNECTION 0x1
|
#define PORT_STATUS_CONNECTION 0x0001
|
||||||
#define PORT_STATUS_ENABLE 0x2
|
#define PORT_STATUS_ENABLE 0x0002
|
||||||
#define PORT_STATUS_SUSPEND 0x4
|
#define PORT_STATUS_SUSPEND 0x0004
|
||||||
#define PORT_STATUS_OVER_CURRENT 0x8
|
#define PORT_STATUS_OVER_CURRENT 0x0008
|
||||||
#define PORT_STATUS_RESET 0x10
|
#define PORT_STATUS_RESET 0x0010
|
||||||
#define PORT_STATUS_POWER 0x100
|
#define PORT_STATUS_POWER 0x0100
|
||||||
#define PORT_STATUS_LOW_SPEED 0x200
|
#define PORT_STATUS_LOW_SPEED 0x0200
|
||||||
|
|
||||||
|
|
||||||
//The feature requests with ports
|
//The feature requests with ports
|
||||||
// USB 1.1 spec page 268
|
// USB 1.1 spec page 268
|
||||||
#define PORT_CONNECTION 0
|
#define PORT_CONNECTION 0
|
||||||
#define PORT_ENABLE 1
|
#define PORT_ENABLE 1
|
||||||
#define PORT_SUSPEND 2
|
#define PORT_SUSPEND 2
|
||||||
#define PORT_OVER_CURRENT 3
|
#define PORT_OVER_CURRENT 3
|
||||||
#define PORT_RESET 4
|
#define PORT_RESET 4
|
||||||
#define PORT_POWER 8
|
#define PORT_POWER 8
|
||||||
#define PORT_LOW_SPEED 9
|
#define PORT_LOW_SPEED 9
|
||||||
#define C_PORT_CONNECTION 16
|
#define C_PORT_CONNECTION 16
|
||||||
#define C_PORT_ENABLE 17
|
#define C_PORT_ENABLE 17
|
||||||
#define C_PORT_SUSPEND 18
|
#define C_PORT_SUSPEND 18
|
||||||
#define C_PORT_OVER_CURRENT 19
|
#define C_PORT_OVER_CURRENT 19
|
||||||
#define C_PORT_RESET 20
|
#define C_PORT_RESET 20
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -154,7 +154,7 @@ free_descriptor_chain(uhci_td *topDescriptor, Stack *stack)
|
|||||||
size_t
|
size_t
|
||||||
read_descriptor_chain(uhci_td *topDescriptor, uint8 *buffer, int32 bufferSize)
|
read_descriptor_chain(uhci_td *topDescriptor, uint8 *buffer, int32 bufferSize)
|
||||||
{
|
{
|
||||||
TRACE(("usb_uhci: reading descriptor chain to buffer 0x%08x\n", buffer, bufferSize));
|
TRACE(("usb_uhci: reading descriptor chain to buffer 0x%08x\n", buffer));
|
||||||
size_t actualSize = 0;
|
size_t actualSize = 0;
|
||||||
uhci_td *current = topDescriptor;
|
uhci_td *current = topDescriptor;
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ read_descriptor_chain(uhci_td *topDescriptor, uint8 *buffer, int32 bufferSize)
|
|||||||
if (!current->buffer_log)
|
if (!current->buffer_log)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
size_t length = (current->status & TD_STATUS_ACTLEN_MASK) + 1;
|
int32 length = (current->status & TD_STATUS_ACTLEN_MASK) + 1;
|
||||||
if (length == TD_STATUS_ACTLEN_NULL + 1)
|
if (length == TD_STATUS_ACTLEN_NULL + 1)
|
||||||
length = 0;
|
length = 0;
|
||||||
|
|
||||||
@ -323,8 +323,8 @@ Queue::AppendDescriptor(uhci_td *descriptor)
|
|||||||
status_t
|
status_t
|
||||||
Queue::AddRequest(Transfer *transfer, bigtime_t timeout)
|
Queue::AddRequest(Transfer *transfer, bigtime_t timeout)
|
||||||
{
|
{
|
||||||
Pipe *pipe = transfer->GetPipe();
|
Pipe *pipe = transfer->TransferPipe();
|
||||||
usb_request_data *requestData = transfer->GetRequestData();
|
usb_request_data *requestData = transfer->RequestData();
|
||||||
bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) > 0;
|
bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) > 0;
|
||||||
|
|
||||||
uhci_td *setupDescriptor = new_descriptor(fStack, pipe, TD_TOKEN_SETUP,
|
uhci_td *setupDescriptor = new_descriptor(fStack, pipe, TD_TOKEN_SETUP,
|
||||||
@ -345,9 +345,9 @@ Queue::AddRequest(Transfer *transfer, bigtime_t timeout)
|
|||||||
statusDescriptor->link_phy = QH_TERMINATE;
|
statusDescriptor->link_phy = QH_TERMINATE;
|
||||||
statusDescriptor->link_log = 0;
|
statusDescriptor->link_log = 0;
|
||||||
|
|
||||||
if (transfer->GetBuffer() && transfer->GetBufferLength() > 0) {
|
if (transfer->Buffer() && transfer->BufferLength() > 0) {
|
||||||
int32 packetSize = 8;
|
int32 packetSize = 8;
|
||||||
int32 bufferLength = transfer->GetBufferLength();
|
int32 bufferLength = transfer->BufferLength();
|
||||||
int32 descriptorCount = (bufferLength + packetSize - 1) / packetSize;
|
int32 descriptorCount = (bufferLength + packetSize - 1) / packetSize;
|
||||||
|
|
||||||
bool dataToggle = true;
|
bool dataToggle = true;
|
||||||
@ -415,9 +415,9 @@ Queue::AddRequest(Transfer *transfer, bigtime_t timeout)
|
|||||||
// without any error so we finished successfully
|
// without any error so we finished successfully
|
||||||
TRACE(("usb_uhci: transfer successful\n"));
|
TRACE(("usb_uhci: transfer successful\n"));
|
||||||
|
|
||||||
uint8 *buffer = (uint8 *)transfer->GetBuffer();
|
uint8 *buffer = (uint8 *)transfer->Buffer();
|
||||||
int32 bufferSize = transfer->GetBufferLength();
|
int32 bufferSize = transfer->BufferLength();
|
||||||
size_t *actualLength = transfer->GetActualLength();
|
size_t *actualLength = transfer->ActualLength();
|
||||||
if (buffer && bufferSize > 0) {
|
if (buffer && bufferSize > 0) {
|
||||||
*actualLength = read_descriptor_chain(
|
*actualLength = read_descriptor_chain(
|
||||||
(uhci_td *)setupDescriptor->link_log,
|
(uhci_td *)setupDescriptor->link_log,
|
||||||
@ -620,10 +620,10 @@ UHCI::SubmitTransfer(Transfer *transfer, bigtime_t timeout)
|
|||||||
TRACE(("usb_uhci: submit packet called\n"));
|
TRACE(("usb_uhci: submit packet called\n"));
|
||||||
|
|
||||||
// Short circuit the root hub
|
// Short circuit the root hub
|
||||||
if (transfer->GetPipe()->DeviceAddress() == fRootHubAddress)
|
if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress)
|
||||||
return fRootHub->SubmitTransfer(transfer);
|
return fRootHub->SubmitTransfer(transfer);
|
||||||
|
|
||||||
if (transfer->GetPipe()->Type() == Pipe::Control)
|
if (transfer->TransferPipe()->Type() == Pipe::Control)
|
||||||
return fQueues[1]->AddRequest(transfer, timeout);
|
return fQueues[1]->AddRequest(transfer, timeout);
|
||||||
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
@ -95,7 +95,7 @@ UHCIRootHub::UHCIRootHub(UHCI *uhci, int8 devicenum)
|
|||||||
status_t
|
status_t
|
||||||
UHCIRootHub::SubmitTransfer(Transfer *transfer)
|
UHCIRootHub::SubmitTransfer(Transfer *transfer)
|
||||||
{
|
{
|
||||||
usb_request_data *request = transfer->GetRequestData();
|
usb_request_data *request = transfer->RequestData();
|
||||||
TRACE(("usb_uhci_roothub: rh_submit_packet called. request: %u\n", request->Request));
|
TRACE(("usb_uhci_roothub: rh_submit_packet called. request: %u\n", request->Request));
|
||||||
|
|
||||||
status_t result = B_ERROR;
|
status_t result = B_ERROR;
|
||||||
@ -103,7 +103,7 @@ UHCIRootHub::SubmitTransfer(Transfer *transfer)
|
|||||||
case RH_GET_STATUS:
|
case RH_GET_STATUS:
|
||||||
if (request->Index == 0) {
|
if (request->Index == 0) {
|
||||||
// Get the hub status -- everything as 0 means all-right
|
// Get the hub status -- everything as 0 means all-right
|
||||||
memset(transfer->GetBuffer(), 0, sizeof(get_status_buffer));
|
memset(transfer->Buffer(), 0, sizeof(get_status_buffer));
|
||||||
result = B_OK;
|
result = B_OK;
|
||||||
break;
|
break;
|
||||||
} else if (request->Index > uhci_hubd.bNbrPorts) {
|
} else if (request->Index > uhci_hubd.bNbrPorts) {
|
||||||
@ -114,11 +114,11 @@ UHCIRootHub::SubmitTransfer(Transfer *transfer)
|
|||||||
|
|
||||||
// Get port status
|
// Get port status
|
||||||
UpdatePortStatus();
|
UpdatePortStatus();
|
||||||
memcpy(transfer->GetBuffer(),
|
memcpy(transfer->Buffer(),
|
||||||
(void *)&fPortStatus[request->Index - 1],
|
(void *)&fPortStatus[request->Index - 1],
|
||||||
transfer->GetBufferLength());
|
transfer->BufferLength());
|
||||||
|
|
||||||
*(transfer->GetActualLength()) = transfer->GetBufferLength();
|
*(transfer->ActualLength()) = transfer->BufferLength();
|
||||||
result = B_OK;
|
result = B_OK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -137,33 +137,33 @@ UHCIRootHub::SubmitTransfer(Transfer *transfer)
|
|||||||
|
|
||||||
switch (request->Value) {
|
switch (request->Value) {
|
||||||
case RH_DEVICE_DESCRIPTOR:
|
case RH_DEVICE_DESCRIPTOR:
|
||||||
memcpy(transfer->GetBuffer(), (void *)&uhci_devd,
|
memcpy(transfer->Buffer(), (void *)&uhci_devd,
|
||||||
transfer->GetBufferLength());
|
transfer->BufferLength());
|
||||||
*(transfer->GetActualLength()) = transfer->GetBufferLength();
|
*(transfer->ActualLength()) = transfer->BufferLength();
|
||||||
result = B_OK;
|
result = B_OK;
|
||||||
break;
|
break;
|
||||||
case RH_CONFIG_DESCRIPTOR:
|
case RH_CONFIG_DESCRIPTOR:
|
||||||
memcpy(transfer->GetBuffer(), (void *)&uhci_confd,
|
memcpy(transfer->Buffer(), (void *)&uhci_confd,
|
||||||
transfer->GetBufferLength());
|
transfer->BufferLength());
|
||||||
*(transfer->GetActualLength()) = transfer->GetBufferLength();
|
*(transfer->ActualLength()) = transfer->BufferLength();
|
||||||
result = B_OK;
|
result = B_OK;
|
||||||
break;
|
break;
|
||||||
case RH_INTERFACE_DESCRIPTOR:
|
case RH_INTERFACE_DESCRIPTOR:
|
||||||
memcpy(transfer->GetBuffer(), (void *)&uhci_intd,
|
memcpy(transfer->Buffer(), (void *)&uhci_intd,
|
||||||
transfer->GetBufferLength());
|
transfer->BufferLength());
|
||||||
*(transfer->GetActualLength()) = transfer->GetBufferLength();
|
*(transfer->ActualLength()) = transfer->BufferLength();
|
||||||
result = B_OK ;
|
result = B_OK ;
|
||||||
break;
|
break;
|
||||||
case RH_ENDPOINT_DESCRIPTOR:
|
case RH_ENDPOINT_DESCRIPTOR:
|
||||||
memcpy(transfer->GetBuffer(), (void *)&uhci_endd,
|
memcpy(transfer->Buffer(), (void *)&uhci_endd,
|
||||||
transfer->GetBufferLength());
|
transfer->BufferLength());
|
||||||
*(transfer->GetActualLength()) = transfer->GetBufferLength();
|
*(transfer->ActualLength()) = transfer->BufferLength();
|
||||||
result = B_OK ;
|
result = B_OK ;
|
||||||
break;
|
break;
|
||||||
case RH_HUB_DESCRIPTOR:
|
case RH_HUB_DESCRIPTOR:
|
||||||
memcpy(transfer->GetBuffer(), (void *)&uhci_hubd,
|
memcpy(transfer->Buffer(), (void *)&uhci_hubd,
|
||||||
transfer->GetBufferLength());
|
transfer->BufferLength());
|
||||||
*(transfer->GetActualLength()) = transfer->GetBufferLength();
|
*(transfer->ActualLength()) = transfer->BufferLength();
|
||||||
result = B_OK;
|
result = B_OK;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user