📄 uqserv.c
字号:
#ifndef lintstatic char *sccsid = "@(#)uqserv.c 4.12 (ULTRIX) 2/14/91";#endif lint/************************************************************************ * * * Copyright (c) 1985 - 1990 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 * UQSSP Port-to-Port Driver * * Abstract: This module contains all of the UQSSP PPD service * functions and the UQSSP-PPD Port Dispatch Table (PDT) * declaration. * * Creator: Mark Parenti Creation Date: July 15, 1985 * * History: * * Feb 1991 Matthew Sacks * In uq_map_buf(), initialize entire buffer * address descriptor, which is a C union, to * 0. This is done using one of the structures * in the union that encompasses all of the bits in * any variation of the union. These bits are all * zeroed to make sure that the MBZ bits in the * buffer descriptor are always zero. * * Dec 1990 Matthew Sacks * Made uq_crash_path return if already re-initing * the path. Rewrote uq_ins_cring and uq_ins_rspring * so that all manipulation of the port rings is SMP * protected. The smp safeness of this code has * been fully exercised. Also, added comments. * * Oct 1990 Matthew Sacks * Fix protocol bug in uq_poll_rspring by not calling up * to scs_msg_rec if the path block is null. This * could have happened when the port is crashing. * Reset UQPath_Is_Up in uq_disable() so that * re-reinits work. Change the PF_ERROR flag to * PF_PORTERROR as per Pete Keilty's SCS fix. * * Stop calling uq_poll_rspring from uq_cleanup as * it is too optimistic to assume any packet we take * is a valid one. Also, clean up below fix by raising * ipl in uq_timer around call to uq_dispatch. * * Sep 1990 Matthew Sacks * SMP bug fix: raised ipl around calls to Lock_pccb * in uq_dispat, uq_conn, uq_dcon, and around call to * Lock_scadb in uq_probe. This is not actually a * bug unless SMP is turned on for DSA. * * 05-Sep-90 Matthew Sacks * Change uq_port_reset so that bisst is only called * once. This is to prevent kdb50 init thrashing. * * 09-Aug-90 Matthew Sacks * SMP bug fix: added missing "else" before Unlock_pccb * in uq_send_msg. * * 03-Aug-90 Ali Rafieymehr * Changes for Stuart Hollander to allow multiple * xmi support. * * May 1990 Matthew Sacks * Implemented SMP safe manipulation of the SSP * ring structures, and SMP safe initialization. * This required substantial changes to most * subroutines. * * Also changed uq_init so that the wait loop on * STEP1 will drop priority during each iteration. * * 26-Dec-89 Robin * 1. Changed the code where RISC buff flush is done to * make the default be a flush and the coded case to * be not flush. This is because the most likely * case will be machines that need the * help and this will require less cahnges in * the new systems we support (maybe?). * * 1-Dec-1989 Matthew S Sacks * 1. Changed uq_port_reset to correctly init the * the KDM70. * 2. Changed uq_probe and uq_port_reset to save the * BDA vector, etc. only once, at probe time, in * case they are needed for a port re-init. * * 09-Nov-89 David E. Eiche DEE0080 * Changed uq_probe() to fill in the new software and * interconnect type fields in the LPIB. * * 09-Nov-89 David E. Eiche DEE0079 * Changed uq_map_buf() to zero unused fields in the buffer * handle. * * 20-Jul-1989 Mark A. Parenti * 1. Change access to ssp registers from structure template * to pointer registers. This is needed because * XMI port registers are not the same size as * the UQ and BI registers. * 2. Make the reset macro into a function call. * 3. Add support for XMI port. * 4. Add code for SSP scratchpad ECO. * * 17-Jan-1989 Todd M. Katz TMK0003 * 1. The macro Scaaddr_lol() has been renamed to Scaaddr_low(). * It now accesses only the low order word( instead of low * order longword ) of a SCA system address. The macro * Scaaddr_hos() has been renamed to Scaaddr_hi(). Make use of * the new macro Scaaadr_mid(). * 2. Include header file ../vaxmsi/msisysap.h. * 3. Use the ../machine link to refer to machine specific header * files. * * 17-Oct-1988 Pete Keilty * Changed uq_cleanup to Kfork uq_init if NULL pb otherwise * we add up in a hung state, failed to init uq port. * * 28-Sept-1988 Mark Parenti * Fix spl bracketing to prevent mchk panics * * 19-Aug-1988 Todd M. Katz TMK0002 * 1. Change all instances of PF_FATALERROR -> PF_ERROR as no * current instance of crashing the local port is fatal. * 2. Make the following modifications to uq_crash_path(): * 1) Apply the path crash severity modifier( ESM_PC ) to * the path crash reason code whenever the path is * open. * 2) Use the SCS path crash reason mapping table * appropriate for the path crash code( scs_map_pc[] * has been split into scs_map_pc[] and scs_map_spc[]). * 3) The routine parameter scsbp ALWAYS points to a * character string of size NAME_SIZE instead of to the * SCS header of a datagram/message buffer whenever SCS * invokes the routine with a reason code of E_SYSAP. * This character string consists of the name of the * local SYSAP responsible for crashing the path. * * 18-July-1988 -- map * Enable last fail packet. Dynamically allocate data structures. * Use sca Cntr_from_num macro to determine controller name. * * 18-Mar-1988 -- map * Clear QB bit in step1r in reinitialization case. This is * already done in probe(). Clearing this bit is necessary * because of a KDB microcode bug. * * 08-Mar-1988 Todd M. Katz TMK0001 * Make the following changes: * 1. Eliminate the routine uq_crash_lport(). It is not used * internally and port drivers are no longer required to supply * for use by SCS a routine for crashing a local port. * 2. Reference scs_map_pc instead of uq_map_genpc and delete the * latter. * 3. Include new header files ../vaxscs/scaparam.h, * ../vaxmsi/msisysap.h, and ../vaxmsi/msiscs.h. * * 08-Mar-1988 -- map * Change ring access to be done in two steps. This is required * because of hardware which reads the ring entry in two reads. * The first read would get the old buffer address and the * second read would get the new high order resulting in an * old command being issued twice. * Also add spl() calls in various places to insure proper ipl. * * 22-Feb-1988 -- Robin * Removed unused ref. to uqdinfo * * 18-Feb-1988 -- map * Make sure have correct IPL when calling poll_cring(). * * 15-Feb-1988 -- map * Cleanup connection handshake code to allow for multiple * simultaneous connect requests. * * 15-Jan-1988 -- map * Enable last fail packet. *//* Libraries and Include Files. */#include "uq.h"#include "../machine/pte.h"#include "../h/param.h"#include "../h/dyntypes.h"#include "../h/systm.h"#include "../h/buf.h"#include "../h/conf.h"#include "../h/kmalloc.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/map.h"#include "../h/vm.h"#include "../h/vmmac.h"#include "../h/dk.h"#include "../h/cmap.h"#include "../h/uio.h"#include "../h/ioctl.h"#include "../h/fs.h"#include "../h/cpudata.h"#include "../h/smp_lock.h"#include "../machine/cpu.h"#include "../../machine/common/cpuconf.h"#include "../io/uba/ubareg.h"#include "../io/uba/ubavar.h"#ifdef vax#include "../machine/mtpr.h"#endif vax#include "../io/sysap/mscp_msg.h"#include "../io/bi/bireg.h"#include "../io/bi/buareg.h"#include "../io/bi/bdareg.h"#include "../io/xmi/xmireg.h"#include "../io/xmi/sspxmi.h"#include "../h/types.h"#include "../h/errlog.h"#include "../h/ksched.h"#include "../io/scs/sca.h"#include "../io/scs/scaparam.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/ci/cippdscs.h"#include "../io/ci/ciscs.h"#include "../io/msi/msiscs.h"#include "../io/bi/bvpscs.h"#include "../io/gvp/gvpscs.h"#include "../io/uba/uqscs.h"#include "../io/scs/scs.h"#include "../io/uba/uqppd.h"#include "../io/uba/uqport.h"#ifdef mips#define WBFLUSH wbflush()#else#define WBFLUSH ;#endif mips/* Routine definitions. */extern struct xmidata xmidata[];extern void uq_conn(),uq_dcon(),uq_init(),uq_cleanup(),uq_error_log(), uq_cred(), uq_port_reset();extern void scs_unix_to_vms();extern struct lock_t lk_scadb;extern PB *uq_get_pb();extern SCSH *uq_alloc_msg(), *uq_remove_msg(), *uq_alloc_dg(), *uq_remove_dg();extern void uq_unmap_buf(), uq_dealloc_msg(), uq_remove_pb(), scs_dealloc_pb(), scs_dealloc_sb(), uq_crash_path(), uq_dealloc_dg(), uq_send_msg(), uq_add_msg(), uq_add_dg(), uq_set_reg();extern u_short scs_map_pc[], scs_map_spc[];extern u_long boottime;extern u_long uq_map_buf(), uq_mstart(), uq_open_path(), uq_mreset(), uq_create_sys(), step_init(), step_wait();PIB uq_pib; /* UQ Path Information Block */SIB uq_sib; /* UQ System Information Block */int uqerror = 1; /* Set if Last Fail Packet is desired */int uqdebug = 0; /* Used to trigger debug printf's */int uq_alloc_cnt = 0;int uq_dealloc_ring = 0;int uq_dealloc_free = 0;PDT uqpdt ={ /* UQSSP Port Dispatch Table */ uq_alloc_dg, /* allocate_dg (supported) */ uq_dealloc_dg, /* deallocate_dg (supported) */ uq_add_dg, /* add_dg (supported) */ uq_remove_dg, /* remove_dg (supported) */ uq_alloc_msg, /* allocate_msg (supported) */ uq_dealloc_msg, /* deallocate_msg (supported) */ uq_add_msg, /* add_msg (supported) */ uq_remove_msg, /* remove_msg (supported) */ uq_send_msg, /* send_msg (supported) */ uq_map_buf, /* map_buffer (supported) */ uq_unmap_buf, /* unmap_buffer (supported) */ uq_open_path, /* open_path (supported) */ uq_crash_path, /* crash_path (supported) */ uq_get_pb, /* get_pb (supported) */ uq_remove_pb, /* remove_pb (supported) */ uq_mreset, /* maint_reset (supported) */ uq_mstart, /* maint_start (supported) */ 0, /* send_dg (unsupported) */ 0, /* send_data (unsupported) */ 0, /* request_data (unsupported) */ 0, /* crash_lport (unsupported) */ 0 /* shutdown (unsupported) */ };int uq_probe(), uqintr(), uq_attach(), uq_timer(), uq_slave();/* * External definitions */extern pccbq scs_lport_db;extern sbq scs_config_db;extern int hz;extern int cpu;extern int numxmi;extern int scs_initialize();extern PB *scs_alloc_pb();extern SB *scs_alloc_sb();extern struct xmidata *get_xmi();/* Port Info Block */extern struct port_info *port_info_ptr[];extern struct uba_ctlr *uqminfo[];#define CTRLNAME "uq"u_short udstd[] = { 0772150, 0772550, 0777550, 0 };struct uba_driver uqdriver ={ uq_probe, uq_slave, uq_attach, 0, udstd, "ra", 0, CTRLNAME, uqminfo, 0};#define DEBUG 1/* Define debugging stuff. */#ifdef DEBUG#define Cprintf if(uqdebug) printf#define Dprintf if( uqdebug >= 2 )cprintf#else#define Cprintf ;#define Dprintf ;#endif#ifdef DEBUG#define printd if (uqdebug) printf#define printd1 if (uqdebug > 1) printf#define printd10 if(uqdebug >= 10) printf#endif#ifdef DEBUG#define cpu_printf(x,y,r) if(uqdebug) {char char_cpu_tmp;\printf("%s: current cpu is %d, the init leader is %d,\the reset leader is %d\n",\r, (char_cpu_tmp = (CURRENT_CPUDATA->cpu_num)), x, y);}#else#define cpu_printf ;#endif#define STEP1MASK 0174177#define STEP1GOOD (UQ_STEP2|(NCMDL2<<3)|NRSPL2)#define STEP2MASK 0174377#define STEP2GOOD (UQ_STEP3|UQ_IE|(Pccb.uq_ivec/4))#define STEP3MASK 0174000#define STEP3GOOD UQ_STEP4#define DELAYTEN 1000#define DEV_IPL 0x17#define b_ubinfo b_resid /* Unibus mapping info per buffer */#define isbda(pccb) (Lpinfo.uq_type == BDA_TYPE)#define SA_W(pccb) *(isbda(pccb)? (Pccb.Uqsaw): (Pccb.Uqsa) )#define Wait_step(mask, result) { \ if ((*Pccb.Uqsa & mask) != result) { \ int count = 0; \ while((*Pccb.Uqsa & mask) != result) { \ DELAY(10000); \ count++; \ if(count > DELAYTEN ) break; \ } \ if(count > DELAYTEN ) { \ Lpinfo.uq_state = S_IDLE; \ Lpinfo.sa = *Pccb.Uqsa; \ uq_error_log( pccb, UQ_RESET_FAIL ); \ uq_disable(pccb, PF_PORTERROR); \ return; \ } \ } \ }/* * * * Name: uq_probe * * Abstract: Probe entry point for configure. This routine will * initialize the controller and set up the required * data structures for SCS. * * Inputs: * * reg - Address of controller * ctlr - Controller number * * * Outputs: * * pccb - Port Command and Control Block allocated * pdt - Address of this port's PDT * pd.uq.uq_ctlr - Controller number * pd.uq.uqaddr - Address of controller device * pd.uq.scs - Address of SCS Accpt/Disconnect buffer * pd.uq.stepxr - Step 1-4 read data * lpinfo.uq.uq_state - Current state of controller * * pcinfo - Table of pccb's indexed by controller number * pc_ptr - Pointer to pccb for this controller * * SMP: lockinit is called to initialize the * the pccb's lock structure * * Return * Values: * * 0 - Controller does not exist or cannot be * initialized. * * sizeof(device) - If the controller exists and can be * initialized the size of the uqdevice * structure is returned. The uqdevice * structure represents the I/O page device * registers. * * * Side * Effects: - The controller is initialized. The necessary * SCS structures are allocated and * initialized. The "system" is made known to * SCS which passes this information on to * interested SYSAP's. * * */int uq_probe(reg, ctlr) caddr_t reg; int ctlr;{ register PCCB *pccb; int count, i, s; struct port_info *pcinfo; UQ_SCP *scp; int intr_dest; u_long intr_vec; struct xmidata *xmidata; struct bda_regs *bdar;#ifdef mips KM_ALLOC(pccb, PCCB *,sizeof(PCCB),KM_SCA, KM_NOW_CL_CA | KM_NOCACHE )#else KM_ALLOC(pccb, PCCB *,sizeof(PCCB),KM_SCA, KM_NOW_CL_CA )#endif mips if ( pccb == (PCCB *)NULL ) return(0); U_long( pccb->size ) = sizeof( PCCB ); /* Size of PCCB */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -