📄 hub.c
字号:
/*
** WASABI-Hot! version 1.2c (Hub sub-unit)
**
**
** -- copyright (c) 2001-2004 by Philips Japan, Ltd. -- All rights reserved --
**
**
** ** This code has been made to check/learn **
** ** the ISP1362/ISP1363 functionalities **
** ** Release 06-Aug-2004 **
**
** OKANO, Akifumi
**
** Application Laboratory, Mobile and Connectivity
** Semiconductors Div, Philips Japan Ltd.
** akifumi.okano@philips.com
** +81-3-3740-4668
*/
/****************************************************************************/
/* includes */
/****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <alloc.h>
#include "_hc_core/atl_mix.h"
#include "_hc_core/dev_ep.h"
#include "_hc_core/port_ctl.h"
#include "_hc_core/transfer.h"
#include "class_dr/hub/hub.h"
#include "ui.h"
#include "general.h"
/****************************************************************************/
/* function prototypes */
/****************************************************************************/
device_instance *create_hub_class_instance( device_instance *dvi_ptr );
void hub_callback( endpoint_info_ptr epi_ptr );
/****************************************************************************/
/* function definitions */
/****************************************************************************/
unsigned short hub_init_commands( device_instance *dvi_ptr )
{
unsigned char buffer[ datalength_of_HUB_DESCRIPTOR ];
hub_instance *hi_ptr;
unsigned char number_of_ports;
unsigned short size;
unsigned short i;
if ( devep_regist_config_descriptors( dvi_ptr, 1, 0 ) )
return ( error );
/* Get hub descriptor */
if ( NULL == create_hub_class_instance( dvi_ptr ) )
mprintf( LIGHTRED, ABORT, "error @ create_hub_class_instance()\r\n" );
// Bus-power turn-on for all ports on the hub.
hi_ptr = (hub_instance *)hub_instance_ptr( dvi_ptr );
number_of_ports = number_of_port_in_hub( dvi_ptr );
for ( i = 1; i <= number_of_ports; i++ )
{
size = 0; // "size" may/may-not be updated by "devep_std_request()" call.
devep_std_request( buffer, dvi_ptr, hub_cls_sp_request_SetPortFeature, PORT_POWER, i, &size );
}
// Set interrupt pipe
if ( (NO_OPEN_ATL_TRANSFER_SLOT == (hi_ptr->tr_index = atlmix_get_open_transfer_index( INTERRUPT_TRANSFER ))) )
mprintf( LIGHTRED, ABORT, "error @ transfer_control_transaction, transfer list full.\r\n" );
hi_ptr->tr_instance_ptr = atlmix_set_transfer( INTERRUPT_TRANSFER, hi_ptr->polling_rate, hi_ptr->tr_index, &(hi_ptr->ep1_data), 1, IN, (dvi_ptr->epi_ptr)[ EpIN ][ 1 ], hub_callback );
return ( 0 );
}
device_instance *create_hub_class_instance( device_instance *dvi_ptr )
{
// This instance will be disposed in function "devep_dispose_device()"
hub_instance *hi_ptr;
unsigned short size = datalength_of_HUB_DESCRIPTOR;
int i;
if ( NULL == (hi_ptr = (hub_instance *)malloc( 4 + sizeof( hub_instance ) )) )
mprintf( LIGHTRED, ABORT, "error @ malloc in create_hub_class_instance()\r\n" );
// Check endpoint characteristics
if ( (dvi_ptr->conf_descriptor).bNumInterfaces != 1 )
mprintf( LIGHTRED, ABORT, "error @ create_hub_class_instance, un-supported hub. (dvi_ptr->conf_descriptor).bNumInterfaces is not 1.\r\n" );
if ( ((dvi_ptr->epi_ptr[ EpIN ][ 1 ])->endpoint_descriptor).bEndpointAddress != 0x81 )
mprintf( LIGHTRED, ABORT, "error @ create_hub_class_instance, un-supported hub. ((dvi_ptr->epi_ptr[ EpIN ][ 1 ])->endpoint_descriptor).bEndpointAddress is not 0x81.\r\n" );
if ( ((dvi_ptr->epi_ptr[ EpIN ][ 1 ])->endpoint_descriptor).wMaxPacketSize != 1 )
mprintf( LIGHTRED, ABORT, "error @ create_hub_class_instance, un-supported hub. ((dvi_ptr->epi_ptr[ EpIN ][ 1 ])->endpoint_descriptor).wMaxPacketSize is not 1.\r\n" );
hi_ptr->polling_rate = ((dvi_ptr->epi_ptr[ EpIN ][ 1 ])->endpoint_descriptor).bInterval;
// Get HUB descriptor
if ( devep_std_request( (hi_ptr->hub_descriptor), dvi_ptr, hub_cls_sp_request_GetHubDescripter, 0, 0, &size ) )
return ( NULL );
dvi_ptr->class_instance_ptr = hi_ptr;
hi_ptr->device_ptr = dvi_ptr;
hi_ptr->number_of_ports = ((hub_descriptor_params *)(&(hi_ptr->hub_descriptor)))->bNbrPorts;
hi_ptr->tr_index = 0xFF;
hi_ptr->tr_instance_ptr = NULL;
for ( i = 0; i < MAX_NUM_OF_PORTS; i++ )
(hi_ptr->portctl_device_on_port)[ i ] = NULL;
dvi_ptr->class_instance_ptr = hi_ptr;
return ( dvi_ptr );
}
unsigned short hub_dispose_process( device_instance *dvi_ptr )
{
hub_instance *hi_ptr;
device_instance *downstream_device_ptr;
int i;
/*
** Stop interrupt transfer to the hub
*/
hi_ptr = (hub_instance *)hub_instance_ptr( dvi_ptr );
atlmix_free_transfer_index( INTERRUPT_TRANSFER, hi_ptr->tr_index );
/*
** Dispose devices at downstream ports
*/
for ( i = 0; i < hi_ptr->number_of_ports; i++ )
{
downstream_device_ptr = (hub_instance_ptr( dvi_ptr )->portctl_device_on_port)[ i ];
if ( NULL != downstream_device_ptr )
devep_dispose_device( &downstream_device_ptr );
}
return ( 0 );
}
void hub_callback( endpoint_info_ptr epi_ptr )
{
hub_event_flag this_event;
if ( atlmix_is_fatal_error( (transfer_instance *)(epi_ptr->transfer_instance) ) )
{
// Device may be detached
atlmix_free_transfer( (transfer_instance *)(epi_ptr->transfer_instance) );
return;
}
this_event.port_status_change_bit_map = *(((transfer_instance *)(epi_ptr->transfer_instance))->data_ptr_base);
atlmix_re_enable_interrupt_transfer( epi_ptr->transfer_instance );
this_event.hub_address = epi_ptr->dev_addr;
this_event.topology_layer = (devep_find_device( this_event.hub_address ))->topology_layer;
// If this event is happened at hub in leaf side in tree, no process will be done at this time.
// The event will be handled by next timing of callback (interrupt transfer ACKed time)
if ( gp_hub_event.hub_address )
if ( gp_hub_event.topology_layer < this_event.topology_layer )
return;
// If this event is happened at hub in root side in tree, over-ride the event.
// Root side event has higher priority
gp_hub_event = this_event;
}
unsigned long hub_read_hub_device_port_status( device_instance *dvi_ptr, unsigned char port )
{
unsigned long data;
unsigned short size;
size = 4;
devep_std_request( (unsigned char *)(&data), dvi_ptr, hub_cls_sp_request_GetPortStatus, 0, port, &size );
return ( data );
}
void hub_reset_hub_device_port( device_instance *dvi_ptr, unsigned char port )
{
unsigned long dummy;
unsigned short size;
size = 0;
devep_std_request( (unsigned char *)(&dummy), dvi_ptr, hub_cls_sp_request_SetPortFeature, PORT_RESET, port, &size );
}
void hub_clear_hub_device_port( device_instance *dvi_ptr, unsigned char port )
{
unsigned long dummy;
unsigned short size;
size = 0;
devep_std_request( (unsigned char *)(&dummy), dvi_ptr, hub_cls_sp_request_ClearPortFeature, C_PORT_CONNECTION, port, &size );
}
void hub_clear_status_change_bits_in_hub( device_instance *dvi_ptr, unsigned char port, unsigned short pos )
{
unsigned long dummy;
unsigned short size;
size = 0;
devep_std_request( (unsigned char *)(&dummy), dvi_ptr, hub_cls_sp_request_ClearPortFeature, pos, port, &size );
}
#if 0
/* GET_STATUS from all ports */
// 4 bytes data getting
for ( i = 0; i < number_of_ports; i++ )
{
size = 4;
devep_std_request( port_status[ i ], dvi_ptr, hub_cls_sp_request_GetPortStatus, 0, (i + 1), &size );
}
for ( i = 0; i < number_of_ports; i++ )
{
if ( port_status[ i ][ 0 ] & 0x01 )
mprintf( WHITE, CONTINUE, "port %d has device on this hub (address %d)\r\n", i + 1, dvi_ptr->address );
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -