2005-04-16 15:20:36 -07:00
/*
*
2012-02-19 19:52:38 -08:00
Copyright ( c ) Eicon Networks , 2002.
2005-04-16 15:20:36 -07:00
*
2012-02-19 19:52:38 -08:00
This source file is supplied for the use with
Eicon Networks range of DIVA Server Adapters .
2005-04-16 15:20:36 -07:00
*
2012-02-19 19:52:38 -08:00
Eicon File Revision : 2.1
2005-04-16 15:20:36 -07:00
*
2012-02-19 19:52:38 -08:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 , or ( at your option )
any later version .
2005-04-16 15:20:36 -07:00
*
2012-02-19 19:52:38 -08:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
See the GNU General Public License for more details .
2005-04-16 15:20:36 -07:00
*
2012-02-19 19:52:38 -08:00
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
2005-04-16 15:20:36 -07:00
*
*/
# include "platform.h"
# include "di_defs.h"
# include "pc.h"
# include "pr_pc.h"
# include "divasync.h"
# define MIPS_SCOM
# include "pkmaint.h" /* pc_main.h, packed in os-dependent fashion */
# include "di.h"
# include "mi_pc.h"
# include "io.h"
2012-02-19 19:52:38 -08:00
extern ADAPTER * adapter [ MAX_ADAPTER ] ;
2005-04-16 15:20:36 -07:00
extern PISDN_ADAPTER IoAdapters [ MAX_ADAPTER ] ;
2012-02-19 19:52:38 -08:00
void request ( PISDN_ADAPTER , ENTITY * ) ;
static void pcm_req ( PISDN_ADAPTER , ENTITY * ) ;
2005-04-16 15:20:36 -07:00
/* --------------------------------------------------------------------------
2012-02-19 19:52:38 -08:00
local functions
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
# define ReqFunc(N) \
static void Request # # N ( ENTITY * e ) \
{ if ( IoAdapters [ N ] ) ( * IoAdapters [ N ] - > DIRequest ) ( IoAdapters [ N ] , e ) ; }
2005-04-16 15:20:36 -07:00
ReqFunc ( 0 )
ReqFunc ( 1 )
ReqFunc ( 2 )
ReqFunc ( 3 )
ReqFunc ( 4 )
ReqFunc ( 5 )
ReqFunc ( 6 )
ReqFunc ( 7 )
ReqFunc ( 8 )
ReqFunc ( 9 )
ReqFunc ( 10 )
ReqFunc ( 11 )
ReqFunc ( 12 )
ReqFunc ( 13 )
ReqFunc ( 14 )
ReqFunc ( 15 )
IDI_CALL Requests [ MAX_ADAPTER ] =
{ & Request0 , & Request1 , & Request2 , & Request3 ,
2012-02-19 19:52:38 -08:00
& Request4 , & Request5 , & Request6 , & Request7 ,
& Request8 , & Request9 , & Request10 , & Request11 ,
& Request12 , & Request13 , & Request14 , & Request15
2005-04-16 15:20:36 -07:00
} ;
/*****************************************************************************/
/*
This array should indicate all new services , that this version of XDI
is able to provide to his clients
2012-02-19 19:52:38 -08:00
*/
static byte extended_xdi_features [ DIVA_XDI_EXTENDED_FEATURES_MAX_SZ + 1 ] = {
( DIVA_XDI_EXTENDED_FEATURES_VALID |
DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR |
DIVA_XDI_EXTENDED_FEATURE_CAPI_PRMS |
2005-04-16 15:20:36 -07:00
# if defined(DIVA_IDI_RX_DMA)
2012-02-19 19:52:38 -08:00
DIVA_XDI_EXTENDED_FEATURE_CMA |
DIVA_XDI_EXTENDED_FEATURE_RX_DMA |
DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA |
2005-04-16 15:20:36 -07:00
# endif
2012-02-19 19:52:38 -08:00
DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC ) ,
0
2005-04-16 15:20:36 -07:00
} ;
/*****************************************************************************/
void
2012-02-19 19:52:38 -08:00
dump_xlog_buffer ( PISDN_ADAPTER IoAdapter , Xdesc * xlogDesc )
{
dword logLen ;
word * Xlog = xlogDesc - > buf ;
word logCnt = xlogDesc - > cnt ;
word logOut = xlogDesc - > out / sizeof ( * Xlog ) ;
DBG_FTL ( ( " %s: ************* XLOG recovery (%d) ************* " ,
& IoAdapter - > Name [ 0 ] , ( int ) logCnt ) )
DBG_FTL ( ( " Microcode: %s " , & IoAdapter - > ProtocolIdString [ 0 ] ) )
for ( ; logCnt > 0 ; - - logCnt )
{
if ( ! GET_WORD ( & Xlog [ logOut ] ) )
{
if ( - - logCnt = = 0 )
break ;
logOut = 0 ;
}
if ( GET_WORD ( & Xlog [ logOut ] ) < = ( logOut * sizeof ( * Xlog ) ) )
{
if ( logCnt > 2 )
{
DBG_FTL ( ( " Possibly corrupted XLOG: %d entries left " ,
( int ) logCnt ) )
}
break ;
}
logLen = ( dword ) ( GET_WORD ( & Xlog [ logOut ] ) - ( logOut * sizeof ( * Xlog ) ) ) ;
DBG_FTL_MXLOG ( ( ( char * ) & Xlog [ logOut + 1 ] , ( dword ) ( logLen - 2 ) ) )
logOut = ( GET_WORD ( & Xlog [ logOut ] ) + 1 ) / sizeof ( * Xlog ) ;
}
DBG_FTL ( ( " %s: ***************** end of XLOG ***************** " ,
& IoAdapter - > Name [ 0 ] ) )
}
2005-04-16 15:20:36 -07:00
/*****************************************************************************/
# if defined(XDI_USE_XLOG)
static char * ( ExceptionCauseTable [ ] ) =
{
2012-02-19 19:52:38 -08:00
" Interrupt " ,
" TLB mod /IBOUND " ,
" TLB load /DBOUND " ,
" TLB store " ,
" Address error load " ,
" Address error store " ,
" Instruction load bus error " ,
" Data load/store bus error " ,
" Syscall " ,
" Breakpoint " ,
" Reverd instruction " ,
" Coprocessor unusable " ,
" Overflow " ,
" TRAP " ,
" VCEI " ,
" Floating Point Exception " ,
" CP2 " ,
" Reserved 17 " ,
" Reserved 18 " ,
" Reserved 19 " ,
" Reserved 20 " ,
" Reserved 21 " ,
" Reserved 22 " ,
" WATCH " ,
" Reserved 24 " ,
" Reserved 25 " ,
" Reserved 26 " ,
" Reserved 27 " ,
" Reserved 28 " ,
" Reserved 29 " ,
" Reserved 30 " ,
" VCED "
} ;
2005-04-16 15:20:36 -07:00
# endif
void
2012-02-19 19:52:38 -08:00
dump_trap_frame ( PISDN_ADAPTER IoAdapter , byte __iomem * exceptionFrame )
{
MP_XCPTC __iomem * xcept = ( MP_XCPTC __iomem * ) exceptionFrame ;
dword __iomem * regs ;
regs = & xcept - > regs [ 0 ] ;
DBG_FTL ( ( " %s: ***************** CPU TRAPPED ***************** " ,
& IoAdapter - > Name [ 0 ] ) )
DBG_FTL ( ( " Microcode: %s " , & IoAdapter - > ProtocolIdString [ 0 ] ) )
DBG_FTL ( ( " Cause: %s " ,
ExceptionCauseTable [ ( READ_DWORD ( & xcept - > cr ) & 0x0000007c ) > > 2 ] ) )
DBG_FTL ( ( " sr 0x%08x cr 0x%08x epc 0x%08x vaddr 0x%08x " ,
READ_DWORD ( & xcept - > sr ) , READ_DWORD ( & xcept - > cr ) ,
READ_DWORD ( & xcept - > epc ) , READ_DWORD ( & xcept - > vaddr ) ) )
DBG_FTL ( ( " zero 0x%08x at 0x%08x v0 0x%08x v1 0x%08x " ,
READ_DWORD ( & regs [ 0 ] ) , READ_DWORD ( & regs [ 1 ] ) ,
READ_DWORD ( & regs [ 2 ] ) , READ_DWORD ( & regs [ 3 ] ) ) )
DBG_FTL ( ( " a0 0x%08x a1 0x%08x a2 0x%08x a3 0x%08x " ,
READ_DWORD ( & regs [ 4 ] ) , READ_DWORD ( & regs [ 5 ] ) ,
READ_DWORD ( & regs [ 6 ] ) , READ_DWORD ( & regs [ 7 ] ) ) )
DBG_FTL ( ( " t0 0x%08x t1 0x%08x t2 0x%08x t3 0x%08x " ,
READ_DWORD ( & regs [ 8 ] ) , READ_DWORD ( & regs [ 9 ] ) ,
READ_DWORD ( & regs [ 10 ] ) , READ_DWORD ( & regs [ 11 ] ) ) )
DBG_FTL ( ( " t4 0x%08x t5 0x%08x t6 0x%08x t7 0x%08x " ,
READ_DWORD ( & regs [ 12 ] ) , READ_DWORD ( & regs [ 13 ] ) ,
READ_DWORD ( & regs [ 14 ] ) , READ_DWORD ( & regs [ 15 ] ) ) )
DBG_FTL ( ( " s0 0x%08x s1 0x%08x s2 0x%08x s3 0x%08x " ,
READ_DWORD ( & regs [ 16 ] ) , READ_DWORD ( & regs [ 17 ] ) ,
READ_DWORD ( & regs [ 18 ] ) , READ_DWORD ( & regs [ 19 ] ) ) )
DBG_FTL ( ( " s4 0x%08x s5 0x%08x s6 0x%08x s7 0x%08x " ,
READ_DWORD ( & regs [ 20 ] ) , READ_DWORD ( & regs [ 21 ] ) ,
READ_DWORD ( & regs [ 22 ] ) , READ_DWORD ( & regs [ 23 ] ) ) )
DBG_FTL ( ( " t8 0x%08x t9 0x%08x k0 0x%08x k1 0x%08x " ,
READ_DWORD ( & regs [ 24 ] ) , READ_DWORD ( & regs [ 25 ] ) ,
READ_DWORD ( & regs [ 26 ] ) , READ_DWORD ( & regs [ 27 ] ) ) )
DBG_FTL ( ( " gp 0x%08x sp 0x%08x s8 0x%08x ra 0x%08x " ,
READ_DWORD ( & regs [ 28 ] ) , READ_DWORD ( & regs [ 29 ] ) ,
READ_DWORD ( & regs [ 30 ] ) , READ_DWORD ( & regs [ 31 ] ) ) )
DBG_FTL ( ( " md 0x%08x|%08x resvd 0x%08x class 0x%08x " ,
READ_DWORD ( & xcept - > mdhi ) , READ_DWORD ( & xcept - > mdlo ) ,
READ_DWORD ( & xcept - > reseverd ) , READ_DWORD ( & xcept - > xclass ) ) )
}
2005-04-16 15:20:36 -07:00
/* --------------------------------------------------------------------------
2012-02-19 19:52:38 -08:00
Real XDI Request function
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void request ( PISDN_ADAPTER IoAdapter , ENTITY * e )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
byte i ;
diva_os_spin_lock_magic_t irql ;
2005-04-16 15:20:36 -07:00
/*
* if the Req field in the entity structure is 0 ,
* we treat this request as a special function call
*/
2012-02-19 19:52:38 -08:00
if ( ! e - > Req )
{
IDI_SYNC_REQ * syncReq = ( IDI_SYNC_REQ * ) e ;
switch ( e - > Rc )
{
2005-04-16 15:20:36 -07:00
# if defined(DIVA_IDI_RX_DMA)
2012-02-19 19:52:38 -08:00
case IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION : {
diva_xdi_dma_descriptor_operation_t * pI = \
& syncReq - > xdi_dma_descriptor_operation . info ;
if ( ! IoAdapter - > dma_map ) {
pI - > operation = - 1 ;
pI - > descriptor_number = - 1 ;
return ;
}
diva_os_enter_spin_lock ( & IoAdapter - > data_spin_lock , & irql , " dma_op " ) ;
if ( pI - > operation = = IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC ) {
pI - > descriptor_number = diva_alloc_dma_map_entry ( \
( struct _diva_dma_map_entry * ) IoAdapter - > dma_map ) ;
if ( pI - > descriptor_number > = 0 ) {
dword dma_magic ;
void * local_addr ;
diva_get_dma_map_entry ( \
( struct _diva_dma_map_entry * ) IoAdapter - > dma_map ,
pI - > descriptor_number ,
& local_addr , & dma_magic ) ;
pI - > descriptor_address = local_addr ;
pI - > descriptor_magic = dma_magic ;
pI - > operation = 0 ;
} else {
pI - > operation = - 1 ;
}
} else if ( ( pI - > operation = = IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE ) & &
( pI - > descriptor_number > = 0 ) ) {
diva_free_dma_map_entry ( ( struct _diva_dma_map_entry * ) IoAdapter - > dma_map ,
pI - > descriptor_number ) ;
pI - > descriptor_number = - 1 ;
pI - > operation = 0 ;
} else {
pI - > descriptor_number = - 1 ;
pI - > operation = - 1 ;
}
diva_os_leave_spin_lock ( & IoAdapter - > data_spin_lock , & irql , " dma_op " ) ;
} return ;
2005-04-16 15:20:36 -07:00
# endif
2012-02-19 19:52:38 -08:00
case IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER : {
diva_xdi_get_logical_adapter_number_s_t * pI = \
& syncReq - > xdi_logical_adapter_number . info ;
pI - > logical_adapter_number = IoAdapter - > ANum ;
pI - > controller = IoAdapter - > ControllerNumber ;
pI - > total_controllers = IoAdapter - > Properties . Adapters ;
} return ;
case IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS : {
diva_xdi_get_capi_parameters_t prms , * pI = & syncReq - > xdi_capi_prms . info ;
memset ( & prms , 0x00 , sizeof ( prms ) ) ;
prms . structure_length = min_t ( size_t , sizeof ( prms ) , pI - > structure_length ) ;
memset ( pI , 0x00 , pI - > structure_length ) ;
prms . flag_dynamic_l1_down = ( IoAdapter - > capi_cfg . cfg_1 & \
DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON ) ? 1 : 0 ;
prms . group_optimization_enabled = ( IoAdapter - > capi_cfg . cfg_1 & \
DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON ) ? 1 : 0 ;
memcpy ( pI , & prms , prms . structure_length ) ;
} return ;
case IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR :
syncReq - > xdi_sdram_bar . info . bar = IoAdapter - > sdram_bar ;
return ;
case IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES : {
dword i ;
diva_xdi_get_extended_xdi_features_t * pI = \
& syncReq - > xdi_extended_features . info ;
pI - > buffer_length_in_bytes & = ~ 0x80000000 ;
if ( pI - > buffer_length_in_bytes & & pI - > features ) {
memset ( pI - > features , 0x00 , pI - > buffer_length_in_bytes ) ;
}
for ( i = 0 ; ( ( pI - > features ) & & ( i < pI - > buffer_length_in_bytes ) & &
( i < DIVA_XDI_EXTENDED_FEATURES_MAX_SZ ) ) ; i + + ) {
pI - > features [ i ] = extended_xdi_features [ i ] ;
}
if ( ( pI - > buffer_length_in_bytes < DIVA_XDI_EXTENDED_FEATURES_MAX_SZ ) | |
( ! pI - > features ) ) {
pI - > buffer_length_in_bytes = \
( 0x80000000 | DIVA_XDI_EXTENDED_FEATURES_MAX_SZ ) ;
}
} return ;
case IDI_SYNC_REQ_XDI_GET_STREAM :
if ( IoAdapter ) {
diva_xdi_provide_istream_info ( & IoAdapter - > a ,
& syncReq - > xdi_stream_info . info ) ;
} else {
syncReq - > xdi_stream_info . info . provided_service = 0 ;
}
return ;
case IDI_SYNC_REQ_GET_NAME :
if ( IoAdapter )
{
strcpy ( & syncReq - > GetName . name [ 0 ] , IoAdapter - > Name ) ;
DBG_TRC ( ( " xdi: Adapter %d / Name '%s' " ,
IoAdapter - > ANum , IoAdapter - > Name ) )
return ;
}
syncReq - > GetName . name [ 0 ] = ' \0 ' ;
break ;
case IDI_SYNC_REQ_GET_SERIAL :
if ( IoAdapter )
{
syncReq - > GetSerial . serial = IoAdapter - > serialNo ;
DBG_TRC ( ( " xdi: Adapter %d / SerialNo %ld " ,
IoAdapter - > ANum , IoAdapter - > serialNo ) )
return ;
}
syncReq - > GetSerial . serial = 0 ;
break ;
case IDI_SYNC_REQ_GET_CARDTYPE :
if ( IoAdapter )
{
syncReq - > GetCardType . cardtype = IoAdapter - > cardType ;
DBG_TRC ( ( " xdi: Adapter %d / CardType %ld " ,
IoAdapter - > ANum , IoAdapter - > cardType ) )
return ;
}
syncReq - > GetCardType . cardtype = 0 ;
break ;
case IDI_SYNC_REQ_GET_XLOG :
if ( IoAdapter )
{
pcm_req ( IoAdapter , e ) ;
return ;
}
e - > Ind = 0 ;
break ;
case IDI_SYNC_REQ_GET_DBG_XLOG :
if ( IoAdapter )
{
pcm_req ( IoAdapter , e ) ;
return ;
}
e - > Ind = 0 ;
break ;
case IDI_SYNC_REQ_GET_FEATURES :
if ( IoAdapter )
{
syncReq - > GetFeatures . features =
( unsigned short ) IoAdapter - > features ;
return ;
}
syncReq - > GetFeatures . features = 0 ;
break ;
case IDI_SYNC_REQ_PORTDRV_HOOK :
if ( IoAdapter )
{
DBG_TRC ( ( " Xdi:IDI_SYNC_REQ_PORTDRV_HOOK - ignored " ) )
return ;
}
break ;
}
if ( IoAdapter )
{
return ;
}
}
DBG_TRC ( ( " xdi: Id 0x%x / Req 0x%x / Rc 0x%x " , e - > Id , e - > Req , e - > Rc ) )
if ( ! IoAdapter )
{
DBG_FTL ( ( " xdi: uninitialized Adapter used - ignore request " ) )
return ;
}
diva_os_enter_spin_lock ( & IoAdapter - > data_spin_lock , & irql , " data_req " ) ;
2005-04-16 15:20:36 -07:00
/*
* assign an entity
*/
2012-02-19 19:52:38 -08:00
if ( ! ( e - > Id & 0x1f ) )
{
if ( IoAdapter - > e_count > = IoAdapter - > e_max )
{
DBG_FTL ( ( " xdi: all Ids in use (max=%d) --> Req ignored " ,
IoAdapter - > e_max ) )
diva_os_leave_spin_lock ( & IoAdapter - > data_spin_lock , & irql , " data_req " ) ;
return ;
}
2005-04-16 15:20:36 -07:00
/*
* find a new free id
*/
2012-02-19 19:52:38 -08:00
for ( i = 1 ; IoAdapter - > e_tbl [ i ] . e ; + + i ) ;
IoAdapter - > e_tbl [ i ] . e = e ;
IoAdapter - > e_count + + ;
e - > No = ( byte ) i ;
e - > More = 0 ;
e - > RCurrent = 0xff ;
}
else
{
i = e - > No ;
}
2005-04-16 15:20:36 -07:00
/*
* if the entity is still busy , ignore the request call
*/
2012-02-19 19:52:38 -08:00
if ( e - > More & XBUSY )
{
DBG_FTL ( ( " xdi: Id 0x%x busy --> Req 0x%x ignored " , e - > Id , e - > Req ) )
if ( ! IoAdapter - > trapped & & IoAdapter - > trapFnc )
{
IoAdapter - > trapFnc ( IoAdapter ) ;
/*
Firs trap , also notify user if supported
*/
if ( IoAdapter - > trapped & & IoAdapter - > os_trap_nfy_Fnc ) {
( * ( IoAdapter - > os_trap_nfy_Fnc ) ) ( IoAdapter , IoAdapter - > ANum ) ;
}
}
diva_os_leave_spin_lock ( & IoAdapter - > data_spin_lock , & irql , " data_req " ) ;
return ;
}
2005-04-16 15:20:36 -07:00
/*
* initialize transmit status variables
*/
2012-02-19 19:52:38 -08:00
e - > More | = XBUSY ;
e - > More & = ~ XMOREF ;
e - > XCurrent = 0 ;
e - > XOffset = 0 ;
2005-04-16 15:20:36 -07:00
/*
* queue this entity in the adapter request queue
*/
2012-02-19 19:52:38 -08:00
IoAdapter - > e_tbl [ i ] . next = 0 ;
if ( IoAdapter - > head )
{
IoAdapter - > e_tbl [ IoAdapter - > tail ] . next = i ;
IoAdapter - > tail = i ;
}
else
{
IoAdapter - > head = i ;
IoAdapter - > tail = i ;
}
2005-04-16 15:20:36 -07:00
/*
* queue the DPC to process the request
*/
2012-02-19 19:52:38 -08:00
diva_os_schedule_soft_isr ( & IoAdapter - > req_soft_isr ) ;
diva_os_leave_spin_lock ( & IoAdapter - > data_spin_lock , & irql , " data_req " ) ;
2005-04-16 15:20:36 -07:00
}
/* ---------------------------------------------------------------------
2012-02-19 19:52:38 -08:00
Main DPC routine
2005-04-16 15:20:36 -07:00
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2012-02-19 19:52:38 -08:00
void DIDpcRoutine ( struct _diva_os_soft_isr * psoft_isr , void * Context ) {
PISDN_ADAPTER IoAdapter = ( PISDN_ADAPTER ) Context ;
ADAPTER * a = & IoAdapter - > a ;
diva_os_atomic_t * pin_dpc = & IoAdapter - > in_dpc ;
if ( diva_os_atomic_increment ( pin_dpc ) = = 1 ) {
do {
if ( IoAdapter - > tst_irq ( a ) )
{
if ( ! IoAdapter - > Unavailable )
IoAdapter - > dpc ( a ) ;
IoAdapter - > clr_irq ( a ) ;
}
IoAdapter - > out ( a ) ;
} while ( diva_os_atomic_decrement ( pin_dpc ) > 0 ) ;
/* ----------------------------------------------------------------
Look for XLOG request ( cards with indirect addressing )
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
if ( IoAdapter - > pcm_pending ) {
struct pc_maint * pcm ;
diva_os_spin_lock_magic_t OldIrql ;
diva_os_enter_spin_lock ( & IoAdapter - > data_spin_lock ,
& OldIrql ,
" data_dpc " ) ;
pcm = ( struct pc_maint * ) IoAdapter - > pcm_data ;
switch ( IoAdapter - > pcm_pending ) {
case 1 : /* ask card for XLOG */
a - > ram_out ( a , & IoAdapter - > pcm - > rc , 0 ) ;
a - > ram_out ( a , & IoAdapter - > pcm - > req , pcm - > req ) ;
IoAdapter - > pcm_pending = 2 ;
break ;
case 2 : /* Try to get XLOG from the card */
if ( ( int ) ( a - > ram_in ( a , & IoAdapter - > pcm - > rc ) ) ) {
a - > ram_in_buffer ( a , IoAdapter - > pcm , pcm , sizeof ( * pcm ) ) ;
IoAdapter - > pcm_pending = 3 ;
}
break ;
case 3 : /* let XDI recovery XLOG */
break ;
}
diva_os_leave_spin_lock ( & IoAdapter - > data_spin_lock ,
& OldIrql ,
" data_dpc " ) ;
}
/* ---------------------------------------------------------------- */
}
2005-04-16 15:20:36 -07:00
}
/* --------------------------------------------------------------------------
2012-02-19 19:52:38 -08:00
XLOG interface
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2005-04-16 15:20:36 -07:00
static void
2012-02-19 19:52:38 -08:00
pcm_req ( PISDN_ADAPTER IoAdapter , ENTITY * e )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
diva_os_spin_lock_magic_t OldIrql ;
int i , rc ;
ADAPTER * a = & IoAdapter - > a ;
struct pc_maint * pcm = ( struct pc_maint * ) & e - > Ind ;
2005-04-16 15:20:36 -07:00
/*
* special handling of I / O based card interface
* the memory access isn ' t an atomic operation !
*/
2012-02-19 19:52:38 -08:00
if ( IoAdapter - > Properties . Card = = CARD_MAE )
{
diva_os_enter_spin_lock ( & IoAdapter - > data_spin_lock ,
& OldIrql ,
" data_pcm_1 " ) ;
IoAdapter - > pcm_data = ( void * ) pcm ;
IoAdapter - > pcm_pending = 1 ;
diva_os_schedule_soft_isr ( & IoAdapter - > req_soft_isr ) ;
diva_os_leave_spin_lock ( & IoAdapter - > data_spin_lock ,
& OldIrql ,
" data_pcm_1 " ) ;
for ( rc = 0 , i = ( IoAdapter - > trapped ? 3000 : 250 ) ; ! rc & & ( i > 0 ) ; - - i )
{
diva_os_sleep ( 1 ) ;
if ( IoAdapter - > pcm_pending = = 3 ) {
diva_os_enter_spin_lock ( & IoAdapter - > data_spin_lock ,
& OldIrql ,
" data_pcm_3 " ) ;
IoAdapter - > pcm_pending = 0 ;
IoAdapter - > pcm_data = NULL ;
diva_os_leave_spin_lock ( & IoAdapter - > data_spin_lock ,
& OldIrql ,
" data_pcm_3 " ) ;
return ;
}
diva_os_enter_spin_lock ( & IoAdapter - > data_spin_lock ,
& OldIrql ,
" data_pcm_2 " ) ;
diva_os_schedule_soft_isr ( & IoAdapter - > req_soft_isr ) ;
diva_os_leave_spin_lock ( & IoAdapter - > data_spin_lock ,
& OldIrql ,
" data_pcm_2 " ) ;
}
diva_os_enter_spin_lock ( & IoAdapter - > data_spin_lock ,
& OldIrql ,
" data_pcm_4 " ) ;
IoAdapter - > pcm_pending = 0 ;
IoAdapter - > pcm_data = NULL ;
diva_os_leave_spin_lock ( & IoAdapter - > data_spin_lock ,
& OldIrql ,
" data_pcm_4 " ) ;
goto Trapped ;
}
2005-04-16 15:20:36 -07:00
/*
* memory based shared ram is accessible from different
* processors without disturbing concurrent processes .
*/
2012-02-19 19:52:38 -08:00
a - > ram_out ( a , & IoAdapter - > pcm - > rc , 0 ) ;
a - > ram_out ( a , & IoAdapter - > pcm - > req , pcm - > req ) ;
for ( i = ( IoAdapter - > trapped ? 3000 : 250 ) ; - - i > 0 ; )
{
diva_os_sleep ( 1 ) ;
rc = ( int ) ( a - > ram_in ( a , & IoAdapter - > pcm - > rc ) ) ;
if ( rc )
{
a - > ram_in_buffer ( a , IoAdapter - > pcm , pcm , sizeof ( * pcm ) ) ;
return ;
}
}
2005-04-16 15:20:36 -07:00
Trapped :
2012-02-19 19:52:38 -08:00
if ( IoAdapter - > trapFnc )
{
int trapped = IoAdapter - > trapped ;
IoAdapter - > trapFnc ( IoAdapter ) ;
/*
Firs trap , also notify user if supported
*/
if ( ! trapped & & IoAdapter - > trapped & & IoAdapter - > os_trap_nfy_Fnc ) {
( * ( IoAdapter - > os_trap_nfy_Fnc ) ) ( IoAdapter , IoAdapter - > ANum ) ;
}
}
2005-04-16 15:20:36 -07:00
}
/*------------------------------------------------------------------*/
/* ram access functions for memory mapped cards */
/*------------------------------------------------------------------*/
2012-02-19 19:52:38 -08:00
byte mem_in ( ADAPTER * a , void * addr )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
byte val ;
volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM ( ( PISDN_ADAPTER ) a - > io ) ;
val = READ_BYTE ( Base + ( unsigned long ) addr ) ;
DIVA_OS_MEM_DETACH_RAM ( ( PISDN_ADAPTER ) a - > io , Base ) ;
return ( val ) ;
2005-04-16 15:20:36 -07:00
}
2012-02-19 19:52:38 -08:00
word mem_inw ( ADAPTER * a , void * addr )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
word val ;
volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM ( ( PISDN_ADAPTER ) a - > io ) ;
val = READ_WORD ( ( Base + ( unsigned long ) addr ) ) ;
DIVA_OS_MEM_DETACH_RAM ( ( PISDN_ADAPTER ) a - > io , Base ) ;
return ( val ) ;
2005-04-16 15:20:36 -07:00
}
2012-02-19 19:52:38 -08:00
void mem_in_dw ( ADAPTER * a , void * addr , dword * data , int dwords )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM ( ( PISDN_ADAPTER ) a - > io ) ;
while ( dwords - - ) {
* data + + = READ_DWORD ( ( Base + ( unsigned long ) addr ) ) ;
addr + = 4 ;
}
DIVA_OS_MEM_DETACH_RAM ( ( PISDN_ADAPTER ) a - > io , Base ) ;
2005-04-16 15:20:36 -07:00
}
2012-02-19 19:52:38 -08:00
void mem_in_buffer ( ADAPTER * a , void * addr , void * buffer , word length )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM ( ( PISDN_ADAPTER ) a - > io ) ;
memcpy_fromio ( buffer , ( Base + ( unsigned long ) addr ) , length ) ;
DIVA_OS_MEM_DETACH_RAM ( ( PISDN_ADAPTER ) a - > io , Base ) ;
2005-04-16 15:20:36 -07:00
}
2012-02-19 19:52:38 -08:00
void mem_look_ahead ( ADAPTER * a , PBUFFER * RBuffer , ENTITY * e )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
PISDN_ADAPTER IoAdapter = ( PISDN_ADAPTER ) a - > io ;
IoAdapter - > RBuffer . length = mem_inw ( a , & RBuffer - > length ) ;
mem_in_buffer ( a , RBuffer - > P , IoAdapter - > RBuffer . P ,
IoAdapter - > RBuffer . length ) ;
e - > RBuffer = ( DBUFFER * ) & IoAdapter - > RBuffer ;
2005-04-16 15:20:36 -07:00
}
2012-02-19 19:52:38 -08:00
void mem_out ( ADAPTER * a , void * addr , byte data )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM ( ( PISDN_ADAPTER ) a - > io ) ;
WRITE_BYTE ( Base + ( unsigned long ) addr , data ) ;
DIVA_OS_MEM_DETACH_RAM ( ( PISDN_ADAPTER ) a - > io , Base ) ;
2005-04-16 15:20:36 -07:00
}
2012-02-19 19:52:38 -08:00
void mem_outw ( ADAPTER * a , void * addr , word data )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM ( ( PISDN_ADAPTER ) a - > io ) ;
WRITE_WORD ( ( Base + ( unsigned long ) addr ) , data ) ;
DIVA_OS_MEM_DETACH_RAM ( ( PISDN_ADAPTER ) a - > io , Base ) ;
2005-04-16 15:20:36 -07:00
}
2012-02-19 19:52:38 -08:00
void mem_out_dw ( ADAPTER * a , void * addr , const dword * data , int dwords )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM ( ( PISDN_ADAPTER ) a - > io ) ;
while ( dwords - - ) {
WRITE_DWORD ( ( Base + ( unsigned long ) addr ) , * data ) ;
addr + = 4 ;
data + + ;
}
DIVA_OS_MEM_DETACH_RAM ( ( PISDN_ADAPTER ) a - > io , Base ) ;
2005-04-16 15:20:36 -07:00
}
2012-02-19 19:52:38 -08:00
void mem_out_buffer ( ADAPTER * a , void * addr , void * buffer , word length )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM ( ( PISDN_ADAPTER ) a - > io ) ;
memcpy_toio ( ( Base + ( unsigned long ) addr ) , buffer , length ) ;
DIVA_OS_MEM_DETACH_RAM ( ( PISDN_ADAPTER ) a - > io , Base ) ;
2005-04-16 15:20:36 -07:00
}
2012-02-19 19:52:38 -08:00
void mem_inc ( ADAPTER * a , void * addr )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM ( ( PISDN_ADAPTER ) a - > io ) ;
byte x = READ_BYTE ( Base + ( unsigned long ) addr ) ;
WRITE_BYTE ( Base + ( unsigned long ) addr , x + 1 ) ;
DIVA_OS_MEM_DETACH_RAM ( ( PISDN_ADAPTER ) a - > io , Base ) ;
2005-04-16 15:20:36 -07:00
}
/*------------------------------------------------------------------*/
/* ram access functions for io-mapped cards */
/*------------------------------------------------------------------*/
2012-02-19 19:52:38 -08:00
byte io_in ( ADAPTER * a , void * adr )
{
byte val ;
byte __iomem * Port = DIVA_OS_MEM_ATTACH_PORT ( ( PISDN_ADAPTER ) a - > io ) ;
outppw ( Port + 4 , ( word ) ( unsigned long ) adr ) ;
val = inpp ( Port ) ;
DIVA_OS_MEM_DETACH_PORT ( ( PISDN_ADAPTER ) a - > io , Port ) ;
return ( val ) ;
}
word io_inw ( ADAPTER * a , void * adr )
{
word val ;
byte __iomem * Port = DIVA_OS_MEM_ATTACH_PORT ( ( PISDN_ADAPTER ) a - > io ) ;
outppw ( Port + 4 , ( word ) ( unsigned long ) adr ) ;
val = inppw ( Port ) ;
DIVA_OS_MEM_DETACH_PORT ( ( PISDN_ADAPTER ) a - > io , Port ) ;
return ( val ) ;
}
void io_in_buffer ( ADAPTER * a , void * adr , void * buffer , word len )
{
byte __iomem * Port = DIVA_OS_MEM_ATTACH_PORT ( ( PISDN_ADAPTER ) a - > io ) ;
byte * P = ( byte * ) buffer ;
if ( ( long ) adr & 1 ) {
outppw ( Port + 4 , ( word ) ( unsigned long ) adr ) ;
* P = inpp ( Port ) ;
P + + ;
adr = ( ( byte * ) adr ) + 1 ;
len - - ;
if ( ! len ) {
DIVA_OS_MEM_DETACH_PORT ( ( PISDN_ADAPTER ) a - > io , Port ) ;
return ;
}
}
outppw ( Port + 4 , ( word ) ( unsigned long ) adr ) ;
inppw_buffer ( Port , P , len + 1 ) ;
DIVA_OS_MEM_DETACH_PORT ( ( PISDN_ADAPTER ) a - > io , Port ) ;
}
void io_look_ahead ( ADAPTER * a , PBUFFER * RBuffer , ENTITY * e )
{
byte __iomem * Port = DIVA_OS_MEM_ATTACH_PORT ( ( PISDN_ADAPTER ) a - > io ) ;
outppw ( Port + 4 , ( word ) ( unsigned long ) RBuffer ) ;
( ( PISDN_ADAPTER ) a - > io ) - > RBuffer . length = inppw ( Port ) ;
inppw_buffer ( Port , ( ( PISDN_ADAPTER ) a - > io ) - > RBuffer . P , ( ( PISDN_ADAPTER ) a - > io ) - > RBuffer . length + 1 ) ;
e - > RBuffer = ( DBUFFER * ) & ( ( ( PISDN_ADAPTER ) a - > io ) - > RBuffer ) ;
2005-04-16 15:20:36 -07:00
DIVA_OS_MEM_DETACH_PORT ( ( PISDN_ADAPTER ) a - > io , Port ) ;
2012-02-19 19:52:38 -08:00
}
void io_out ( ADAPTER * a , void * adr , byte data )
{
byte __iomem * Port = DIVA_OS_MEM_ATTACH_PORT ( ( PISDN_ADAPTER ) a - > io ) ;
outppw ( Port + 4 , ( word ) ( unsigned long ) adr ) ;
outpp ( Port , data ) ;
DIVA_OS_MEM_DETACH_PORT ( ( PISDN_ADAPTER ) a - > io , Port ) ;
}
void io_outw ( ADAPTER * a , void * adr , word data )
{
byte __iomem * Port = DIVA_OS_MEM_ATTACH_PORT ( ( PISDN_ADAPTER ) a - > io ) ;
outppw ( Port + 4 , ( word ) ( unsigned long ) adr ) ;
outppw ( Port , data ) ;
DIVA_OS_MEM_DETACH_PORT ( ( PISDN_ADAPTER ) a - > io , Port ) ;
}
void io_out_buffer ( ADAPTER * a , void * adr , void * buffer , word len )
{
byte __iomem * Port = DIVA_OS_MEM_ATTACH_PORT ( ( PISDN_ADAPTER ) a - > io ) ;
byte * P = ( byte * ) buffer ;
if ( ( long ) adr & 1 ) {
outppw ( Port + 4 , ( word ) ( unsigned long ) adr ) ;
outpp ( Port , * P ) ;
P + + ;
adr = ( ( byte * ) adr ) + 1 ;
len - - ;
if ( ! len ) {
DIVA_OS_MEM_DETACH_PORT ( ( PISDN_ADAPTER ) a - > io , Port ) ;
return ;
}
}
outppw ( Port + 4 , ( word ) ( unsigned long ) adr ) ;
outppw_buffer ( Port , P , len + 1 ) ;
DIVA_OS_MEM_DETACH_PORT ( ( PISDN_ADAPTER ) a - > io , Port ) ;
}
void io_inc ( ADAPTER * a , void * adr )
{
byte x ;
byte __iomem * Port = DIVA_OS_MEM_ATTACH_PORT ( ( PISDN_ADAPTER ) a - > io ) ;
outppw ( Port + 4 , ( word ) ( unsigned long ) adr ) ;
x = inpp ( Port ) ;
outppw ( Port + 4 , ( word ) ( unsigned long ) adr ) ;
outpp ( Port , x + 1 ) ;
2005-04-16 15:20:36 -07:00
DIVA_OS_MEM_DETACH_PORT ( ( PISDN_ADAPTER ) a - > io , Port ) ;
}
/*------------------------------------------------------------------*/
/* OS specific functions related to queuing of entities */
/*------------------------------------------------------------------*/
2012-02-19 19:52:38 -08:00
void free_entity ( ADAPTER * a , byte e_no )
{
PISDN_ADAPTER IoAdapter ;
diva_os_spin_lock_magic_t irql ;
IoAdapter = ( PISDN_ADAPTER ) a - > io ;
diva_os_enter_spin_lock ( & IoAdapter - > data_spin_lock , & irql , " data_free " ) ;
IoAdapter - > e_tbl [ e_no ] . e = NULL ;
IoAdapter - > e_count - - ;
diva_os_leave_spin_lock ( & IoAdapter - > data_spin_lock , & irql , " data_free " ) ;
}
void assign_queue ( ADAPTER * a , byte e_no , word ref )
{
PISDN_ADAPTER IoAdapter ;
diva_os_spin_lock_magic_t irql ;
IoAdapter = ( PISDN_ADAPTER ) a - > io ;
diva_os_enter_spin_lock ( & IoAdapter - > data_spin_lock , & irql , " data_assign " ) ;
IoAdapter - > e_tbl [ e_no ] . assign_ref = ref ;
IoAdapter - > e_tbl [ e_no ] . next = ( byte ) IoAdapter - > assign ;
IoAdapter - > assign = e_no ;
diva_os_leave_spin_lock ( & IoAdapter - > data_spin_lock , & irql , " data_assign " ) ;
}
byte get_assign ( ADAPTER * a , word ref )
{
PISDN_ADAPTER IoAdapter ;
diva_os_spin_lock_magic_t irql ;
byte e_no ;
IoAdapter = ( PISDN_ADAPTER ) a - > io ;
diva_os_enter_spin_lock ( & IoAdapter - > data_spin_lock ,
& irql ,
" data_assign_get " ) ;
for ( e_no = ( byte ) IoAdapter - > assign ;
e_no & & IoAdapter - > e_tbl [ e_no ] . assign_ref ! = ref ;
e_no = IoAdapter - > e_tbl [ e_no ] . next ) ;
diva_os_leave_spin_lock ( & IoAdapter - > data_spin_lock ,
& irql ,
" data_assign_get " ) ;
return e_no ;
}
void req_queue ( ADAPTER * a , byte e_no )
{
PISDN_ADAPTER IoAdapter ;
diva_os_spin_lock_magic_t irql ;
IoAdapter = ( PISDN_ADAPTER ) a - > io ;
diva_os_enter_spin_lock ( & IoAdapter - > data_spin_lock , & irql , " data_req_q " ) ;
IoAdapter - > e_tbl [ e_no ] . next = 0 ;
if ( IoAdapter - > head ) {
IoAdapter - > e_tbl [ IoAdapter - > tail ] . next = e_no ;
IoAdapter - > tail = e_no ;
}
else {
IoAdapter - > head = e_no ;
IoAdapter - > tail = e_no ;
}
diva_os_leave_spin_lock ( & IoAdapter - > data_spin_lock , & irql , " data_req_q " ) ;
}
byte look_req ( ADAPTER * a )
{
PISDN_ADAPTER IoAdapter ;
IoAdapter = ( PISDN_ADAPTER ) a - > io ;
return ( ( byte ) IoAdapter - > head ) ;
}
void next_req ( ADAPTER * a )
{
PISDN_ADAPTER IoAdapter ;
diva_os_spin_lock_magic_t irql ;
IoAdapter = ( PISDN_ADAPTER ) a - > io ;
diva_os_enter_spin_lock ( & IoAdapter - > data_spin_lock , & irql , " data_req_next " ) ;
IoAdapter - > head = IoAdapter - > e_tbl [ IoAdapter - > head ] . next ;
if ( ! IoAdapter - > head ) IoAdapter - > tail = 0 ;
diva_os_leave_spin_lock ( & IoAdapter - > data_spin_lock , & irql , " data_req_next " ) ;
2005-04-16 15:20:36 -07:00
}
/*------------------------------------------------------------------*/
/* memory map functions */
/*------------------------------------------------------------------*/
2012-02-19 19:52:38 -08:00
ENTITY * entity_ptr ( ADAPTER * a , byte e_no )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
PISDN_ADAPTER IoAdapter ;
IoAdapter = ( PISDN_ADAPTER ) a - > io ;
return ( IoAdapter - > e_tbl [ e_no ] . e ) ;
2005-04-16 15:20:36 -07:00
}
2012-02-19 19:52:38 -08:00
void * PTR_X ( ADAPTER * a , ENTITY * e )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
return ( ( void * ) e - > X ) ;
2005-04-16 15:20:36 -07:00
}
2012-02-19 19:52:38 -08:00
void * PTR_R ( ADAPTER * a , ENTITY * e )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
return ( ( void * ) e - > R ) ;
2005-04-16 15:20:36 -07:00
}
2012-02-19 19:52:38 -08:00
void * PTR_P ( ADAPTER * a , ENTITY * e , void * P )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
return P ;
2005-04-16 15:20:36 -07:00
}
2012-02-19 19:52:38 -08:00
void CALLBACK ( ADAPTER * a , ENTITY * e )
2005-04-16 15:20:36 -07:00
{
2012-02-19 19:52:38 -08:00
if ( e & & e - > callback )
e - > callback ( e ) ;
2005-04-16 15:20:36 -07:00
}