📄 ci_init.c
字号:
( void )ci_log_dev_attn( pccb, I_LPORT_INIT, LOG_NOREGS ); if( ci_first_port == 0 ) { ci_first_port = Scaaddr_low( pccb->lpinfo.addr ); } Compute_lbcrc( pccb ) if( ppr & PPR_DIAG_INFO ) { switch( Cluster_size( ppr )) { case 0: pccb->lpinfo.Max_port = (( pccb->lpinfo.type.hwtype == HPT_CIKMF ) ? CSZ_8 - 1 : CSZ_16 - 1 ); break; case 1: pccb->lpinfo.Max_port = CSZ_32 - 1; break; case 2: pccb->lpinfo.Max_port = CSZ_64 - 1; break; case 3: pccb->lpinfo.Max_port = CSZ_128 - 1; break; default: pccb->lpinfo.Max_port = 0; break; } } else { if( Cluster_oldsize( ppr ) == 0 ) { pccb->lpinfo.Max_port = CSZ_16 - 1; } else { pccb->lpinfo.Max_port = 0; } } if( pccb->lpinfo.Max_port ) { if( pccb->lpinfo.Max_port > CIPPD_MAXPATHS ) { pccb->lpinfo.Max_port = CIPPD_MAXPATHS; } for( mrltab = pccb->Mrltab; mrltab->ram; mrltab++ ) { if( mrltab->ram == pccb->Fn_level && mrltab->rom == pccb->Rom_level ) { if( mrltab->warn == UCODE_WARNING ) { ( void )ci_log_dev_attn( pccb, W_UCODE_WARN, LOG_NOREGS ); } break; } } if( mrltab->ram == 0 && pccb->Fn_level <= pccb->Max_fn_level && pccb->Rom_level <= pccb->Max_rom_level ) { /* XCD&DASH temp */ if(( pccb->lpinfo.type.hwtype == HPT_CIXCD ) || ( pccb->lpinfo.type.hwtype == HPT_CIKMF )) { } else { status = FE_BADUCODE; } } } else { status = FE_BADMAXPORT; } if( status ) { pccb->Fsmstatus.broken = 1; ( void )ci_crash_lport( pccb, status, NULL ); } } else { ( void )ci_log_dev_attn( pccb, I_LPORT_REINIT, LOG_NOREGS ); } if( status == 0 && ci_maint_timer ) { ( void )ci_notify_port( pccb ); } Unlock_pccb( pccb ) if( status == 0 ) { ( void )cippd_start( pccb ); } } else if( !pccb->Fsmstatus.broken && --pccb->Reinit_tries ) { Pccb_fork( pccb, ci_init_port, PANIC_PCCBFB ) Unlock_pccb( pccb ) } else { for( q = &pccb->Dfreeq, qend = &pccb->Mfreeq; q <= qend; ++q ) { Flushq( pccb, q ) } if( !pccb->Fsmstatus.broken ) { pccb->Fsmstatus.broken = 1; ( void )ci_unmap_port( pccb ); } Unlock_pccb( pccb ) Lock_scadb() Lock_pccb( pccb ) Remove_entry( pccb->flink ) Unlock_pccb( pccb ) Unlock_scadb() if( pccb->Lpstatus.init ) { ( void )cprintf( "%4s\t- permanently offline( local port ? )\n", ( u_char * )&pccb->lpinfo.name ); pccb->Ciadap->pccb = NULL; if( pccb->Asb ) KM_FREE(( char * )pccb->Asb, KM_SCA ) KM_FREE(( char * )pccb, KM_SCA ) } else { cprintf( "%4s\t- permanently shutting down( local port %u )\n", ( u_char * )&pccb->lpinfo.name, Scaaddr_low( pccb->lpinfo.addr )); } } ( void )splx( save_ipl );}/* Name: ci_probe - Probe a Local CI Port * * Abstract: This routine probes a newly discovered CI port culminating in * its first initialization. Any encountered errors abort the CI * port probing. * * The following CI hardware port types are currently supported: * * CI750, CI780, CIBCI, CIBCA-AA, CIBCA-BA, CIXCD * * Inputs: * * 0 - Interrupt processor level * SBR - System Page Table Address processor register * SLR - System Page Table Length processor register * ci_adap - Vector of CI Adapter Interface Blocks * ci_black_hole - CI black hole mapping page pointer * ci_cippdburst - CI PPD port polling burst size * ci_cippdcontact - CI PPD port polling contact frequency * ci_maint_intrvl - CI port maintenance timer interval * ci_max_reinits - CI max number consecutive reinitializations * ci_pdt - CI Port Dispatch Table * ci_ucode_type - CI functional microcode type * ci780_regoff - CI750/CI780 register offsets * ci7b_mrltable - CI750/CI780/CIBCI Microcode Revision Table * cibca_aa_mrltab - CIBCA-AA Functional Microcode Revision Table * cibca_ba_mrltab - CIBCA-BA Functional Microcode Revision Table * cibca_regoff - CIBCA register offsets * cibci_regoff - CIBCI register offsets * cinum - CI adapter number * cixcd_mrltable - CIXCD Functional Microcode Revision Table * cixcd_regoff - CIXCD register offsets * gvp_bddb - Generic Vaxport Buffer Descriptor Database * gvp_max_bds - Size of system-wide buffer descriptor table * hpt - Hardware port type * interconnect - Interconnect type * ioaddr - Adapter I/O space virtual address * scs_dg_size - Maximum application datagram size * scs_lport_db - System-wide local port database queue head * scs_msg_size - Maximum application message size * Sysmap - System Page Table * * Outputs: * * 0 - Interrupt processor level * ci_adap - Vector of CI Adapter Interface Blocks * ci_bhole_pfn - CI black hole mapping page page frame number * ci_black_hole - CI black hole mapping page pointer * ci_ucode_type - CI functional microcode type * pccb - Port Command and Control Block pointer * ( INITIALIZED as required ) * scs_lport_db - System-wide local port database queue * * SMP: No locks are required even though the PCCB and SCA database are * manipulated. This function is only called during system * initialization and at that time only the processor executing * this code is operational. This guarantees uncompromised access * to all data structures without locking the PCCB or the SCA * database. * * PCCB lock structure is initialized. */voidci_probe( cinum, ioaddr, interconnect, hpt, ciadap ) u_long cinum; register u_char *ioaddr; u_long interconnect; u_long hpt; register CIADAP *ciadap;{ register PCCB *pccb; register u_long status = 0; static u_long initialized = 0; u_long save_ipl = Splscs(); register u_long **regoffptr; /* The steps involved in probing a CI port are as follows: * * 1. IPL is synchronized to IPL_SCS. * 2. SCS is initialized. * 3. The Generic Vaxport Driver is initialized. * 4. A black hole mapping page is allocated. * 5. The CI functional microcode type is ascertained. * 6. A PCCB is allocated. * 7. Presence of CI functional microcode of the appropriate type is * verified( CI750, CI780, CIBCI, and CIBCA-AA only ). * 8. The PCCB is initialized. * 9. The CI port is disabled. * 10. The PCCB is inserted into the system-wide local port database. * 11. Initialization of the CI port is scheduled through forking. * 12. IPL is restored. * * Steps 2-5 constitute CI port driver initialization and are only executed * during probing of the very first local CI port encountered during device * auto-configuration. The remaining steps constitute the actual probing * of the specified local CI port and are executed whenever this routine is * invoked. Any errors( Steps 2-7 ) encountered during either portion of * this routine immediately abort probing of the current local CI port * following logging of the fatal event. The interrupt service routine for * the local CI port is also switched to the ci_unmapped_isr(), the routine * responsible for handling interrupts on unmapped local CI ports. Any * subsequent interrupts on the inoperative local port are discarded. * * NOTE: CIBCA-AA functional microcode is self identifying. It possesses a * 512 byte header which allows it to be uniquely identified as being * for a CIBCA-AA. The other type of functional microcode, CI780 * microcode for CI750/CI780/CIBCI ports, has no such header, and is * not self identifying, but can never be confused with CIBCA-AA * functional microcode. Therefore, CI functional microcode identity * is ascertained( Step 6 ) by determining whether it is CIBCA_AA * microcode, and assuming it is CI780 functional microcode if this * determination fails. * * NOTE: Certain CI hardware port types( CIBCA-BA, CIXCD ) do not require * functional microcode to be loaded. All needed microcode is * onboard. Lack of onboard functional microcode in CI ports of * these hardware types is regarded as a fatal error. The event is * logged and probing of the local CI port is aborted. * * NOTE: All PCCB pointers to adapter registers which are not used by a * local port because of its hardware port type are zeroed. This * includes: * * 1. Pointers to the maintenance address and maintenance data * port registers( not required by CIBCA-BA and CIXCD local * ports because they possess onboard functional microcode ). * 2. Pointers to the configuration register( not required by * CIBCA and CIXCD local ports because they do not define it ). * * NOTE: The PCCB fork block is only used for clean up and initialization * of the local port. Therefore, it should always be available for * the port's first initialization. */ if( initialized == 0 ) { if(( status = scs_initialize()) != RET_SUCCESS || ( status = gvp_initialize()) != RET_SUCCESS ) { status = ( status == RET_ALLOCFAIL ) ? FE_INIT_NOMEM : FE_INIT_ZEROID; } else { KM_ALLOC( ci_black_hole, u_char *, NBPG, KM_SCA, KM_NOW_CL_CA ) if( ci_black_hole ) { status = 0; ci_bhole_pfn = btop((( u_long )ci_bhole_pfn ) & BHOLE_MASK ); if( ci_ucode ) { if( Cibca_aa_ucode( ci_ucode )) { ci_ucode_type = UCODE_CIBCA; } else { ci_ucode_type = UCODE_CI780; } } } else { status = FE_INIT_NOMEM; } } if( status == 0 ) { initialized = 1; } else { ( void )ci_log_initerr( cinum, interconnect, hpt, status ); ci_isr[ cinum ].isr = ci_unmapped_isr; ( void )splx( save_ipl ); return; } } KM_ALLOC( pccb, PCCB *, sizeof( PCCB ), KM_SCA, KM_NOW_CL_CA ) if( pccb ) { ci_isr[ cinum ].pccb = pccb; pccb->Ciadap = ciadap; pccb->Ciisr = &ci_isr[ cinum ]; } else { ( void )ci_log_initerr( cinum, interconnect, hpt, FE_INIT_NOMEM ); ci_isr[ cinum ].isr = ci_unmapped_isr; ( void )splx( save_ipl ); return; } switch(( pccb->Interconnect = interconnect )) { case ICT_SBICMI: if( hpt == HPT_CI780 || hpt == HPT_CI750 ) { if( ci_ucode ) { if( ci_ucode_type == UCODE_CI780 ) { regoffptr = ci780_regoff; pccb->Dg_cache = CI7B_DG_CACHE; pccb->Msg_cache = CI7B_MSG_CACHE; pccb->Max_fn_level = CI7B_MAX_RAM; pccb->Max_rom_level = CI7B_MAX_ROM; pccb->Mrltab = ci7b_mrltable; pccb->Load_ucode = ci7b_load; pccb->Start_port = ci7b_start; pccb->Disable_port = ci7b_disable; } else { status = FE_INIT_MISMTCH; } } else { status = FE_INIT_NOUCODE; } } else { status = FE_INIT_UNKHPT; } break; case ICT_BI: { register struct biic_regs *biic = ( struct biic_regs * )ioaddr; pccb->Bityp = ( u_long * )&biic->biic_typ; pccb->Bictrl = ( u_long * )&biic->biic_ctrl; pccb->Bierr = ( u_long * )&biic->biic_err; pccb->Biint_dst = ( u_long * )&biic->biic_int_dst; pccb->Bibci_ctrl = ( u_long * )&biic->biic_bci_ctrl; pccb->Biint_ctrl = ( u_long * )&biic->biic_int_ctrl; switch( hpt ) { case HPT_CIBCI: if( ci_ucode ) { if( ci_ucode_type == UCODE_CI780 ) { regoffptr = cibci_regoff; pccb->Dg_cache = CI7B_DG_CACHE; pccb->Msg_cache = CI7B_MSG_CACHE; pccb->Max_fn_level = CI7B_MAX_RAM; pccb->Max_rom_level = CI7B_MAX_ROM; pccb->Mrltab = ci7b_mrltable; pccb->Load_ucode = ci7b_load; pccb->Start_port = ci7b_start; pccb->Disable_port = ci7b_disable; } else { status = FE_INIT_MISMTCH; } } else { status = FE_INIT_NOUCODE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -