Summary: Merge with development branch
Patches applied: * n.reedijk@planet.nl--nielx-2003/usb-busses--development--0.1--patch-7 Created memory area for the framelist * n.reedijk@planet.nl--nielx-2003/usb-busses--development--0.1--patch-8 Fix the iobase offset, so that the thing actually is correct * n.reedijk@planet.nl--nielx-2003/usb-busses--development--0.1--patch-9 Device Address 0 is reserved. 1 is the one for root hub * n.reedijk@planet.nl--nielx-2003/usb-busses--development--0.1--patch-10 Changed packet to transfer * n.reedijk@planet.nl--nielx-2003/usb-busses--development--0.1--patch-11 Merge with Axels changes git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7669 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
0f6609e85c
commit
e3964db291
@ -4,5 +4,6 @@ AddResources uhci : uhci.rdef ;
|
||||
|
||||
R5KernelAddon uhci : [ FDirName kernel busses usb ] :
|
||||
uhci.c
|
||||
util.c
|
||||
;
|
||||
|
||||
|
@ -64,22 +64,41 @@ typedef struct
|
||||
uint16 Length;
|
||||
} usb_request_data;
|
||||
|
||||
// Describes the internal organs of an usb packet
|
||||
typedef struct usb_packet_t
|
||||
{
|
||||
uint16 pipe;
|
||||
uint8 *requestdata;
|
||||
uint8 *buffer;
|
||||
int16 bufferlength;
|
||||
size_t *actual_length;
|
||||
int16 address; //!!!! TEMPORARY ... or is it?
|
||||
} usb_packet_t;
|
||||
// Describes the internals of a pipe
|
||||
enum Direction { In , Out , Default };
|
||||
enum Speed { LowSpeed , NormalSpeed };
|
||||
|
||||
typedef struct usb_pipe_t
|
||||
{
|
||||
enum Direction direction;
|
||||
enum Speed speed;
|
||||
int8 deviceid;
|
||||
uint8 endpoint;
|
||||
} usb_pipe_t;
|
||||
|
||||
|
||||
// Describes the internal organs of an usb packet
|
||||
typedef struct usb_transfer_t
|
||||
{
|
||||
//Data that is related to the transfer
|
||||
usb_pipe_t *pipe;
|
||||
uint8 *buffer;
|
||||
size_t bufferlength;
|
||||
size_t *actual_length;
|
||||
bigtime_t timeout;
|
||||
status_t status;
|
||||
|
||||
//For control transfers
|
||||
usb_request_data *request;
|
||||
} usb_transfer_t;
|
||||
|
||||
//
|
||||
//
|
||||
typedef struct host_controller_info
|
||||
{
|
||||
module_info info;
|
||||
status_t (*hwstart)(void);
|
||||
status_t (*SubmitPacket)(usb_packet_t *);
|
||||
status_t (*SubmitPacket)(usb_transfer_t *);
|
||||
} host_controller_info;
|
||||
|
||||
#endif //HOST_CONTROLLER_INFO_H
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "uhci.h"
|
||||
#include "util.h"
|
||||
#include "host_controller.h"
|
||||
|
||||
#define UHCI_DEBUG
|
||||
@ -38,8 +39,8 @@ void silent( const char * , ... ) {}
|
||||
|
||||
|
||||
static status_t init_hardware(void);
|
||||
static status_t submit_packet( usb_packet_t *packet );
|
||||
static status_t rh_submit_packet( usb_packet_t *packet );
|
||||
static status_t submit_packet( usb_transfer_t *transfer );
|
||||
static status_t rh_submit_packet( usb_transfer_t *transfer );
|
||||
static void rh_update_port_status(void);
|
||||
//static int32 uhci_interrupt( void *d );
|
||||
|
||||
@ -172,7 +173,8 @@ init_hardware(void)
|
||||
//Initialise the host controller
|
||||
m_data = (uhci_properties_t *)malloc( sizeof( uhci_properties_t ) );
|
||||
m_data->pcii = m_device;
|
||||
m_data->reg_base = m_device->u.h0.base_registers[0];
|
||||
m_data->reg_base = m_pcimodule->read_pci_config(m_data->pcii->bus, m_data->pcii->device, m_data->pcii->function, 0x20 , 4 ) ^ 1;
|
||||
TRACE( "USB UHCI: iospace offset: %lx\n" , m_data->reg_base );
|
||||
m_data->rh_address = 255; //Invalidate the RH address
|
||||
{
|
||||
/* enable pci address access */
|
||||
@ -198,12 +200,22 @@ init_hardware(void)
|
||||
m_data->port_status[0].status , m_data->port_status[1].status );
|
||||
|
||||
//Set up the frame list
|
||||
/*m_data->framearea = map_physical_memory( "uhci framelist" , m_data->framelist_phy ,
|
||||
4096 , B_ANY_KERNEL_BLOCK_ADDRESS ,
|
||||
B_WRITE_AREA , m_data->framelist );
|
||||
m_data->framearea = alloc_mem( &(m_data->framelist[0]) , &(m_data->framelist_phy) ,
|
||||
4096 , "uhci framelist" );
|
||||
if ( m_data->framearea < B_OK )
|
||||
{
|
||||
TRACE( "USB UHCI: init_hardware(): unable to create an area for the frame pointer list\n" );
|
||||
free( item );
|
||||
put_module( B_PCI_MODULE_NAME );
|
||||
return ENODEV;
|
||||
}
|
||||
|
||||
//!!!!!!!!!!!!!! Check the area
|
||||
*/
|
||||
//Make all frame list entries invalid
|
||||
for( i = 0 ; i < 1024 ; i++ )
|
||||
(int32)(m_data->framelist[i]) = 0x1;
|
||||
|
||||
//Set base pointer
|
||||
m_pcimodule->write_io_32( m_data->reg_base + UHCI_FRBASEADD , (int32)(m_data->framelist_phy) );
|
||||
|
||||
// Install the interrupt handler
|
||||
//install_io_interrupt_handler( m_data->pcii->h0.interrupt_line ,
|
||||
@ -215,23 +227,24 @@ init_hardware(void)
|
||||
}
|
||||
|
||||
/* ++++++++++
|
||||
Inserting packets in the queue
|
||||
Inserting transfers in the queue
|
||||
++++++++++ */
|
||||
status_t submit_packet( usb_packet_t *packet )
|
||||
status_t submit_packet( usb_transfer_t *transfer )
|
||||
{
|
||||
dprintf( "uhci submit_packet(): CALLED\n");
|
||||
//Do the following:
|
||||
//1. Check if the packet really belongs to this bus -- no way of doing that now
|
||||
//2. Acquire the spinlock of the packet -- still needs to be fixed
|
||||
|
||||
if ( packet->address == 0 ) //First device of a bus has address 0 per definition
|
||||
if ( transfer->pipe->deviceid == 1 ) //First device of a bus has address 1 per definition
|
||||
{
|
||||
rh_submit_packet( packet );
|
||||
rh_submit_packet( transfer );
|
||||
goto out;
|
||||
}
|
||||
//4. Determine the type of transfer and send it to the proper function
|
||||
//5. Release the spinlock
|
||||
out:
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/* ++++++++++
|
||||
@ -300,9 +313,9 @@ usb_hub_descriptor uhci_hubd =
|
||||
};
|
||||
|
||||
status_t
|
||||
rh_submit_packet( usb_packet_t *packet )
|
||||
rh_submit_packet( usb_transfer_t *transfer )
|
||||
{
|
||||
usb_request_data *request = (usb_request_data *)packet->requestdata;
|
||||
usb_request_data *request = transfer->request;
|
||||
status_t retval;
|
||||
|
||||
uint16 port; //used in RH_CLEAR/SET_FEATURE
|
||||
@ -315,7 +328,7 @@ rh_submit_packet( usb_packet_t *packet )
|
||||
if ( request->Index == 0 )
|
||||
{
|
||||
//Get the hub status -- everything as 0 means that it is all-rigth
|
||||
memset( packet->buffer , NULL , sizeof(get_status_buffer) );
|
||||
memset( transfer->buffer , NULL , sizeof(get_status_buffer) );
|
||||
retval = B_OK;
|
||||
break;
|
||||
}
|
||||
@ -327,8 +340,8 @@ rh_submit_packet( usb_packet_t *packet )
|
||||
}
|
||||
//Get port status
|
||||
rh_update_port_status();
|
||||
memcpy( packet->buffer , (void *)&(m_data->port_status[request->Index - 1]) , packet->bufferlength );
|
||||
*(packet->actual_length) = packet->bufferlength;
|
||||
memcpy( transfer->buffer , (void *)&(m_data->port_status[request->Index - 1]) , transfer->bufferlength );
|
||||
*(transfer->actual_length) = transfer->bufferlength;
|
||||
retval = B_OK;
|
||||
break;
|
||||
|
||||
@ -349,28 +362,28 @@ rh_submit_packet( usb_packet_t *packet )
|
||||
switch ( request->Value )
|
||||
{
|
||||
case RH_DEVICE_DESCRIPTOR:
|
||||
memcpy( packet->buffer , (void *)&uhci_devd , packet->bufferlength );
|
||||
*(packet->actual_length) = packet->bufferlength;
|
||||
memcpy( transfer->buffer , (void *)&uhci_devd , transfer->bufferlength );
|
||||
*(transfer->actual_length) = transfer->bufferlength;
|
||||
retval = B_OK;
|
||||
break;
|
||||
case RH_CONFIG_DESCRIPTOR:
|
||||
memcpy( packet->buffer , (void *)&uhci_confd , packet->bufferlength );
|
||||
*(packet->actual_length) = packet->bufferlength;
|
||||
memcpy( transfer->buffer , (void *)&uhci_confd , transfer->bufferlength );
|
||||
*(transfer->actual_length) = transfer->bufferlength;
|
||||
retval = B_OK;
|
||||
break;
|
||||
case RH_INTERFACE_DESCRIPTOR:
|
||||
memcpy( packet->buffer , (void *)&uhci_intd , packet->bufferlength );
|
||||
*(packet->actual_length) = packet->bufferlength;
|
||||
memcpy( transfer->buffer , (void *)&uhci_intd , transfer->bufferlength );
|
||||
*(transfer->actual_length) = transfer->bufferlength;
|
||||
retval = B_OK ;
|
||||
break;
|
||||
case RH_ENDPOINT_DESCRIPTOR:
|
||||
memcpy( packet->buffer , (void *)&uhci_endd , packet->bufferlength );
|
||||
*(packet->actual_length) = packet->bufferlength;
|
||||
memcpy( transfer->buffer , (void *)&uhci_endd , transfer->bufferlength );
|
||||
*(transfer->actual_length) = transfer->bufferlength;
|
||||
retval = B_OK ;
|
||||
break;
|
||||
case RH_HUB_DESCRIPTOR:
|
||||
memcpy( packet->buffer , (void *)&uhci_hubd , packet->bufferlength );
|
||||
*(packet->actual_length) = packet->bufferlength;
|
||||
memcpy( transfer->buffer , (void *)&uhci_hubd , transfer->bufferlength );
|
||||
*(transfer->actual_length) = transfer->bufferlength;
|
||||
retval = B_OK;
|
||||
break;
|
||||
default:
|
||||
@ -403,6 +416,11 @@ rh_submit_packet( usb_packet_t *packet )
|
||||
TRACE("UHCI: RH_CLEAR_FEATURE called. Feature: %u!\n" , request->Value );
|
||||
switch( request->Value )
|
||||
{
|
||||
case PORT_RESET:
|
||||
port = m_pcimodule->read_io_16( m_data->reg_base + UHCI_PORTSC1 + (request->Index - 1 ) * 2 );
|
||||
port &= ~UHCI_PORTSC_RESET;
|
||||
TRACE( "UHCI rh: port %x Clear RESET\n" , port );
|
||||
m_pcimodule->write_io_16( m_data->reg_base + UHCI_PORTSC1 + (request->Index - 1 ) * 2 , port );
|
||||
case C_PORT_CONNECTION:
|
||||
port = m_pcimodule->read_io_16( m_data->reg_base + UHCI_PORTSC1 + (request->Index - 1 ) * 2 );
|
||||
port = port & UHCI_PORTSC_DATAMASK;
|
||||
@ -414,7 +432,7 @@ rh_submit_packet( usb_packet_t *packet )
|
||||
default:
|
||||
retval = EINVAL;
|
||||
break;
|
||||
} //switch( packet->value)
|
||||
} //switch( transfer->value)
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -435,7 +453,7 @@ rh_update_port_status(void)
|
||||
uint16 newchange = 0;
|
||||
|
||||
uint16 portsc = m_pcimodule->read_io_16( m_data->reg_base + UHCI_PORTSC1 + i * 2 );
|
||||
dprintf( "USB UHCI: port status: 0x%x\n" , portsc );
|
||||
dprintf( "USB UHCI: port: %x status: 0x%x\n" , UHCI_PORTSC1 + i * 2 , portsc );
|
||||
//Set all individual bits
|
||||
if ( portsc & UHCI_PORTSC_CURSTAT )
|
||||
newstatus |= PORT_STATUS_CONNECTION;
|
||||
|
113
src/add-ons/kernel/busses/usb/util.c
Normal file
113
src/add-ons/kernel/busses/usb/util.c
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* BeOS Driver for Intel ICH AC'97 Link interface
|
||||
*
|
||||
* Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <Errors.h>
|
||||
#include <OS.h>
|
||||
#include <string.h>
|
||||
|
||||
//#define DEBUG 2
|
||||
|
||||
//#include "debug.h"
|
||||
#include "util.h"
|
||||
|
||||
spinlock slock = 0;
|
||||
|
||||
uint32 round_to_pagesize(uint32 size);
|
||||
|
||||
cpu_status lock(void)
|
||||
{
|
||||
cpu_status status = disable_interrupts();
|
||||
acquire_spinlock(&slock);
|
||||
return status;
|
||||
}
|
||||
|
||||
void unlock(cpu_status status)
|
||||
{
|
||||
release_spinlock(&slock);
|
||||
restore_interrupts(status);
|
||||
}
|
||||
|
||||
uint32 round_to_pagesize(uint32 size)
|
||||
{
|
||||
return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
|
||||
}
|
||||
|
||||
area_id alloc_mem(void **log, void **phy, size_t size, const char *name)
|
||||
{
|
||||
physical_entry pe;
|
||||
void * logadr;
|
||||
area_id areaid;
|
||||
status_t rv;
|
||||
|
||||
dprintf("allocating %ld bytes for %s\n",size,name);
|
||||
|
||||
size = round_to_pagesize(size);
|
||||
areaid = create_area(name, &logadr, B_ANY_KERNEL_ADDRESS,size,B_FULL_LOCK | B_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA);
|
||||
if (areaid < B_OK) {
|
||||
dprintf("couldn't allocate area %s\n",name);
|
||||
return B_ERROR;
|
||||
}
|
||||
rv = get_memory_map(logadr,size,&pe,1);
|
||||
if (rv < B_OK) {
|
||||
delete_area(areaid);
|
||||
dprintf("couldn't map %s\n",name);
|
||||
return B_ERROR;
|
||||
}
|
||||
memset(logadr,0,size);
|
||||
if (log)
|
||||
*log = logadr;
|
||||
if (phy)
|
||||
*phy = pe.address;
|
||||
dprintf("area = %ld, size = %ld, log = %#08lX, phy = %#08lX\n",areaid,size,(uint32)logadr,(uint32)(pe.address));
|
||||
return areaid;
|
||||
}
|
||||
|
||||
/* This is not the most advanced method to map physical memory for io access.
|
||||
* Perhaps using B_ANY_KERNEL_ADDRESS instead of B_ANY_KERNEL_BLOCK_ADDRESS
|
||||
* makes the whole offset calculation and relocation obsolete. But the code
|
||||
* below does work, and I can't test if using B_ANY_KERNEL_ADDRESS also works.
|
||||
*/
|
||||
area_id map_mem(void **log, void *phy, size_t size, const char *name)
|
||||
{
|
||||
uint32 offset;
|
||||
void *phyadr;
|
||||
void *mapadr;
|
||||
area_id area;
|
||||
|
||||
dprintf("mapping physical address %p with %#lx bytes for %s\n",phy,size,name);
|
||||
|
||||
offset = (uint32)phy & (B_PAGE_SIZE - 1);
|
||||
phyadr = (char *)phy - offset;
|
||||
size = round_to_pagesize(size + offset);
|
||||
area = map_physical_memory(name, phyadr, size, B_ANY_KERNEL_BLOCK_ADDRESS, B_READ_AREA | B_WRITE_AREA, &mapadr);
|
||||
*log = (char *)mapadr + offset;
|
||||
|
||||
dprintf("physical = %p, logical = %p, offset = %#lx, phyadr = %p, mapadr = %p, size = %#lx, area = %#lx\n",
|
||||
phy, *log, offset, phyadr, mapadr, size, area);
|
||||
|
||||
return area;
|
||||
}
|
41
src/add-ons/kernel/busses/usb/util.h
Normal file
41
src/add-ons/kernel/busses/usb/util.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* BeOS Driver for Intel ICH AC'97 Link interface
|
||||
*
|
||||
* Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
area_id alloc_mem(void **log, void **phy, size_t size, const char *name);
|
||||
area_id map_mem(void **log, void *phy, size_t size, const char *name);
|
||||
|
||||
cpu_status lock(void);
|
||||
void unlock(cpu_status status);
|
||||
|
||||
extern spinlock slock;
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user