📄 mscp_subr.c
字号:
#ifndef lintstatic char *sccsid = "@(#)mscp_subr.c 4.3 (ULTRIX) 2/12/91";#endif lint/************************************************************************ * * * Copyright (c) 1987 - 1989 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************ * * * Facility: Systems Communication Architecture * Disk Class Driver * * Abstract: This module contains all routines necessary to * implement the disk MSCP. * * Author: David E. Eiche Creation Date: September 30, 1985 * * History: * * 11-Feb-1991 Pete Keilty * Changed use of NRSPID constant to a variable defined in mscp_data.c * nrspid. This will allow for adjustable rspid table size on a * system basic if needed. * To Do - nrspid size based on the credits per controller multiplied * by the number of controllers. * * 04-Dec-1990 Pete Keilty * Changed mscp_control() checking of CRE_NEW_PATH event. * Added new routine mscp_adapt_check which checks if this * controller should be attached to this adapter as specified * in the config file. This is an attempt to static load * balance over multiple adapters. Also if the connection is * not the this adapter set a system_poll in timeout for 60sec. * If the other connection does not come in use what is there. * * 13-Mar-1990 David E. Eiche DEE0083 * Fix mscp_dealloc_msg() to get the address of the next waiting * request block. The code got mangled during the ISIS merge. * * 21-Jul-1989 David E. Eiche DEE0070 * Change reference from MSLG_FM_DSK_TRN to MSLG_FM_DISK_TRN. * Change reference from MSLG_FM_BUS_ADR to MSLG_FM_BUS_ADDR. * * 11-Jul-1989 Tim Burke * Modify mscp_poll_wait to wait at least one 15 second interval before * concluding that all controllers have been identified. * * 16-May-1989 Pete Keilty * Change mscp_restart_next to check restart queue is empty by * comparing restart.flink with restart. * * 05-May-1989 Tim Burke * Merged 3.1 changes into the pu and isis pools. * * 31-Mar-1989 Pete Keilty * Fixed alloc rspid Remove_entry to use rtp->flink; * * 15-Mar-1989 Tim Burke * Changed splx( IPL_SCS ) to Splscs(); * Changed queue manipulations to use the following macros: * insque ..... Insert_entry * remque ..... Remove_entry * remqck ..... Remove_entry and check to see if any elements on queue. * * 07-Mar-1989 Todd M. Katz TMK0002 * 1. Include header file ../vaxmsi/msisysap.h. * 2. Use the ../machine link to refer to machine specific header files. * * 28-Dec-1988 Tim Burke * Added the new error log format MSLG_FM_IBMSENSE to mscp_logerr() to * handle informational error logs from the TA90. * * 20-Oct-1988 Pete Keilty * Change mscp_poll_wait to use timeout() to do timing * instead of DELAY. DELAY raises IPL on CVAX processors * and blocks interrupts for an extended period. * * 17-Oct-1988 Pete Keilty * Added untimeout to mscp_alloc_reqb(). * * 28-Sep-1988 David E. Eiche DEE0057 * Change panic message formats to make them consistent and * eliminate unnecessary panic messages. * * 09-Sep-1988 David E. Eiche DEE0056 * Move initialization of request state from mscp_conqrestart * in mscp_conpol.c to mscp_restart_next. This fixes a bug in * which the connection management request block was having * its state erroneously initialized. * * 07-Sep-1988 Larry Cohen * Add 15 second delay to mscp_poll_wait routine so that installation * catches more disks. Need to come up with a better way to wait. * * 06-Sep-1988 David E. Eiche DEE0054 * Fix code which caused disks to hang when a second loss of * connection occurred while recovering from the first. * * 27-Jul-1988 Pete Keilty * Changed datagram routine to check for bbr busy and transfer * datagram to bbr code. Also added new logerr routine. * * 17-Jul-1988 David E. Eiche DEE0047 * Add routine mscp_avail_attn to process available attention * messages. Call it from mscp_message. * * 17-Jul-1988 David E. Eiche DEE0046 * Change mscp_control to call mscp_get_connb directly, so * that new path events can be responded to directly. * * 17-July-1988 David E. Eiche DEE0045 * Move mscp_find_model to mscp_config.c. * * * 08-Jul-1988 Pete Keilty * Added case MSLG_FM_REPLACE for errlogging in datagram routine. * * 23-Jun-1988 David E. Eiche DEE0041 * Fixed mscp_send_msg to put the connection management request * block in the active queue when there are requests waiting for credits. * * 16-June-1988 Larry Cohen * Add global variable mscp_polls that is incremented for each * connection attempt and decremented for each connection completion. * The system waits in init_main for mscp_polls to go to zero so that * autoconfigure output can be delayed until the disks/tapes have * been sized. * * 08-Jun-1988 David E. Eiche DEE0040 * Added a new routine mscp_service_bufferq which is called periodically * from mscp_timer when the buffer wait queue on a connection is not * empty. The routine attempts to allocate buffers for requests waiting * on the queue. * * 02-Jun-1988 Ricky S. Palmer * Removed inclusion of header file ../vaxmsi/msisysap.h * * 02-Apr-1988 David E. Eiche DEE0021 * Move sleep out of KM_ALLOC into mscp_alloc_reqb to * eliminate a sleep on interrupt stack double panic. * * 12-Feb-1988 David E. Eiche DEE0014 * Change references to Insq and Remq macros to call the * underlying insque and remqck functions directly. * * 02-Feb-1988 David E. Eiche DEE0011 * Remove buf structure queuing code from mscp_alloc_reqb. * Also rearrange mscp_timer code that detects waiting map * requests. * * 15-Jan-1988 Todd M. Katz TMK0001 * Include new header file ../vaxmsi/msisysap.h. *//**//* Libraries and Include Files. */#include "../h/types.h"#include "../h/time.h"#include "../h/param.h"#include "../h/kmalloc.h"#include "../h/buf.h"#include "../h/errno.h"#include "../h/ioctl.h"#include "../h/devio.h"#include "../h/file.h"#ifdef mips#include "../h/systm.h"#endif mips#include "../fs/ufs/fs.h"#include "../h/errlog.h"#include "../machine/pte.h"#include "../h/vmmac.h"#include "../io/scs/sca.h"#include "../io/ci/cippdsysap.h"#include "../io/ci/cisysap.h"#include "../io/msi/msisysap.h"#include "../io/bi/bvpsysap.h"#include "../io/gvp/gvpsysap.h"#include "../io/uba/uqsysap.h"#include "../io/sysap/sysap.h"#include "../io/uba/ubavar.h"#include "../io/sysap/mscp_msg.h"#include "../io/sysap/mscp_defs.h"#include "../io/sysap/mscp_bbrdefs.h"/**//* External variables and routines. */extern u_long scs_alloc_msg();extern u_long scs_dealloc_msg();extern u_long scs_map_buf();extern u_long scs_send_msg();extern u_long scs_queue_dgs();extern u_long scs_unmap_buf();extern int wakeup();extern CONNB * mscp_get_connb();extern UNITB * mscp_get_unitb();extern RSPID_TBL mscp_rspid_tbl[];extern LISTHD mscp_rspid_lh;extern LISTHD mscp_rspid_wait_lh;extern u_long mscp_gbl_flags;extern int hz;extern int nrspid;extern int rspid_wq_cnt;extern int mscp_adapt_check();void mscp_avail_attn();void mscp_dealloc_all();void mscp_dispatch();void mscp_reserve_credit();void mscp_restart_next();void mscp_service_mapq();void mscp_service_bufferq();void mscp_service_creditq();void mscp_unstall_unit();/**//* * * Name: mscp_dispatch - Finite state machine dispatcher. * * Abstract: * * Inputs: * * Outputs: * * * Return NONE * Values: */void mscp_dispatch( event, rp ) register u_long event; register REQB *rp;{ register u_long state; register STATE *sp; /* The following "do forever" allows redispatching when a non-NULL * event is returned by an action routine. */ for( ;; ) { state = rp->state; sp = rp->state_tbl + ( state * ( EV_MAXEVENT + 1 ) + event ); rp->state = sp->new_state; /* If the event code returned by the action routine is NULL, * break out of the "do forever" and exit. Otherwise, dispatch * the new event. */ if(( event = ( *sp->action_rtn )( event, rp )) == EV_NULL ) break; } return;}/**//* * * Name: mscp_invevent - Process invalid event. * * Abstract: * * Inputs: * * Outputs: * * * Return NONE * Values: */u_long mscp_invevent( event, rp ) register u_long event; REQB *rp;{ register u_long state = rp->state; printf( "mscp_invevent: invalid event %d in state %d, reqb %x\n", event, state, rp ); panic( "mscp_invevent: fatal mscp error\n" );}/**//* * * Name: mscp_noaction - Null action routine. * * Abstract: * * Inputs: * * Outputs: * * * Return NONE * Values: */u_long mscp_noaction( event, rp ) register u_long event; REQB *rp;{ return( EV_NULL );}/**//* * * Name: mscp_timer - provide connection/resource timing services. * * Abstract: * * Inputs: * * Outputs: * * * Return NONE * Values: */voidmscp_timer( clp ) register CLASSB *clp;{ register CONNB *cp; int s; /* Raise the IPL to synchronize with SCS. */ s = Splscs(); /* If system polling is requested, start up the poller. */ if( clp->flags.need_poll ) mscp_system_poll( clp ); /* Scan through the list of known connections. */ for( cp = clp->flink; cp != ( CONNB * )&clp->flink; cp = cp->flink ) { /* If command timeouts are active on the connection and the timeout * interval has expired, call connection management with a timeout * event. */ if(( cp->cmdtmo_intvl != 0 ) && ( --cp->cmdtmo_intvl == 0 )) mscp_dispatch( EV_TIMEOUT, &cp->timeout_reqb ); /* If the resource wait queue timing threshhold has been reached and * the either the buffer or mapping wait queue is not empty, service * the waiting requests and reset the timeout interval. */ if( cp->rsrctmo_intvl == 0 ) { if( cp->buffer_wq.flink != ( REQB * )&cp->buffer_wq.flink ) mscp_service_bufferq( cp ); if( cp->map_wq.flink != ( REQB * )&cp->map_wq.flink ) mscp_service_mapq( cp ); cp->rsrctmo_intvl = RSRC_WAIT_TMO; } else { --cp->rsrctmo_intvl; } } /* Restore the entry IPL, start another timer interval, and exit. */ ( void )splx( s ); ( void )timeout( mscp_timer, ( caddr_t )clp, hz ); return;}/**//* * * Name: mscp_control - Process asynchronous connection events. * * Abstract: * * Inputs: * * Outputs: * * * Return NONE * Values: */voidmscp_control( event, cmsp ) register u_short event; register CMSB *cmsp;{ register CONNB *cp; register REQB *rp; register CLASSB *clp; /* Store the CMSB address in the request block and dispatch * on asynchronous event type. Note that cmsp->aux contains the * class block address in the new system case, but contains the * connection block address in all other cases. */ if( event == CRE_NEW_PATH ) { clp = ( CLASSB * )cmsp->aux; if( mscp_adapt_check( cmsp )) { cp = mscp_get_connb( clp, &cmsp->sysid, &cmsp->rport_addr, cmsp->lport_name ); if( cp == NULL ) { clp->flags.need_poll = 1; } } else { ( void )timeout( mscp_system_poll, ( caddr_t )clp, hz * 60 ); } } else { cp = ( CONNB * )cmsp->aux; rp = &cp->timeout_reqb; rp->aux = ( u_char * )cmsp; switch( event ) { case CRE_CONN_DONE: mscp_dispatch( EV_CONCOMPLETE, rp ); break; case CRE_PATH_FAILURE: cp->flags.path_fail = 1; /* Fall through */ case CRE_DISCONN_REC: mscp_dispatch( EV_PATHFAILURE, rp ); break; case CRE_DISCONN_DONE: mscp_dispatch( EV_DISCOMPLETE, rp ); break; case CRE_CREDIT_AVAIL: mscp_service_creditq( rp ); break; /* None of the following events should occur. */ case CRE_ACCEPT_DONE: case CRE_BLOCK_DONE: case CRE_CONN_REC: case CRE_REJECT_DONE: default: panic( "mscp_control: unexpected connection management event" ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -