📄 mscp_disk.c
字号:
#ifndef lintstatic char *sccsid = "@(#)mscp_disk.c 4.3 (ULTRIX) 4/4/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 the standard ULTRIX "top half" * routines and other routines specific to the disk * variant of MSCP. * * Author: David E. Eiche Creation Date: September 30, 1985 * * History: * * 02-Apr-1991 Tom Tierney * Fixed recovery problem: mscp_markoffline routine was updated to * check if we are currently in recovery processing and if so, to * return correct new event to continue recovery processing along * with notification via printf of error. This corrects a problem * where the system would hang if recovery failed for a particular * disk. * * 22-Feb-1991 Brian Nadeau * Allow up to 2 minutes for critical devices (swap, dump, root) to * become available and print a status message after we wait the first * minute. * * 09-Nov-1989 David E. Eiche DEE0083 * Fix status subcode test to use MSCP_SC_EXUSE instead of MSCP_ST_OFFLN. * * 23-Oct-1989 Tim Burke * Added support for the exclusive access unit attribute. This involved * adding the DKIOCEXCL ioctl, the set unit characteristics state table * and routines and modifiying online and available command routines. * * 09-Aug-1989 Tim Burke * Added the DEVGETGEOM ioctl which is used to pass disk geometry * information. Removed all references to dk_busy because it is no * longer used. * * 08-Apr-1989 Tom Kong * In mscp_close, took out the floating point operation for mips. * * 15-Mar-1989 Tim Burke * Changed splx( IPL_SCS ) to Splscs(); * * 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. * * 17-Oct-1988 Pete Keilty * Changed mscp_open and mscp_close now does explicit wakeup on * up at end of routine. * * 27-Sep-1988 David E. Eiche DEE0057 * Modified panic message formats to make them consistent. * * 13-Sep-1988 Pete Keilty * Changed transferem routine so the requested lbn is not * over written on a BBR status return which was causing the * wrong lbn to be re-read. * * 19-Aug-1988 Pete Keilty * Added synchronization code to the open and close routine. * New flags busy and close_ip. * * 05-Aug-1988 Pete Keilty * Change mscp_close added sleep on rp. Corrects case where * an open_ip flags is clear out when it should not have been * durning a open. * * 17-Jul-1988 David E. Eiche DEE0045 * Change the get device information ioctl code to use the * connection block as the source of its controller model * information. * * 08-Jul-1988 Pete Keilty * Added accscancm and accscanem routines, ioctl ACC_SCAN code, * and changes force_ip to force_scan_ip where used. * * 02-Jun-1988 Ricky S. Palmer * Removed inclusion of header file ../vaxmsi/msisysap.h * * 16-May-1988 Stephen Reilly * Close is only called once per device. * * 25-Apr-1988 Robin * Added code in ioctl to stop bbr from starting on controllers that do * BBR. Also added code to keep track of I/O which is used by iostat(1). * * 19-Apr-1988 Robin * To stop a unit from going avail when it is still in use the * partition mask was changed to an open counter. A unit can have * several opens on one or more partitions and the unit should * never go avail unless all opens are followed by a close. * * 07-Apr-1988 David E. Eiche DEE0027 * Fix DEE0022 to not panic when booting from an HSC that doesn't * come online. * * 03-Apr-1988 David E. Eiche DEE0024 * Update DEE0013 to make write protection work with open NDELAY. * * 03-Apr-1988 David E. Eiche DEE0023 * Add code to implement exclusive access to disk units, leaving * it commented out pending action by the HSC group. * * 03-Apr-1988 David E. Eiche DEE0022 * Reorder mscp_open routine, eliminate the mscp_onlineinit * routine and references to it, and add an additional test * to mscp_size, to eliminate another race window caused by * the interaction of open NDELAY and close. * * 23-Mar-1988 David E. Eiche DEE0019 * Fix race between open and close in which a partition was * reopened before the close processing had completed. * * 21-Mar-1988 David E. Eiche DEE0018 * Change the mscp_open routine to process NDELAY flag in the * historically approved manner. * * 17-Mar-1988 David E. Eiche DEE0017 * Add jacket routines mscp_bopen, mscp_copen, mscp_bclose and * mscp_cclose whose purpose is to pass a flag into mscp_open and * mscp_close indicating whether the operation is being done in * raw or block mode. The flag is used with the partition index * portion of the dev parameter to determine which partitions are * active. * * 12-Feb-1988 David E. Eiche DEE0013 * Change mscp_onlgtuntem and mscp_ioctl to detect and report * write protection status correctly. * * 02-Feb-1988 David E. Eiche DEE0011 * Change mscp_strategy to sleep if the request block is not * available immediately. Also remove code that initialized * unused request block wait queue. * * 15-Jan-1988 Todd M. Katz TMK0001 * Include new header file ../vaxmsi/msisysap.h. *//**//* Libraries and Include Files. */#include "../h/dk.h"#include "../h/types.h"#include "../h/time.h"#include "../h/param.h"#include "../h/buf.h"#include "../h/errno.h"#include "../h/ioctl.h"#include "../h/devio.h"#include "../h/dkio.h"#include "../h/file.h"#include "../h/conf.h"#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/bi/bvpsysap.h"#include "../io/gvp/gvpsysap.h"#include "../io/msi/msisysap.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"/* External Variables and Routines. */extern REQB *mscp_alloc_reqb();extern u_long mscp_alloc_rspid();extern u_long mscp_bbr_online();extern u_long mscp_bbr_replace();extern void mscp_common_init();extern void mscp_control();extern void mscp_datagram();extern void mscp_dealloc_reqb();extern void mscp_getdefpt();extern void mscp_media_to_ascii();extern void mscp_message();extern u_long mscp_recycle_rspid();extern void mscp_restart_next();extern u_long mscp_send_msg();extern void mscp_system_poll();extern void mscp_timer();extern CLASSB mscp_classb;extern UNITB *mscp_unit_tbl[];extern RSPID_TBL mscp_rspid_tbl[];extern LISTHD mscp_rspid_lh;extern STATE mscp_avl_states[];extern STATE mscp_onl_states[];extern STATE mscp_rec_states[];extern STATE mscp_accscan_states[];extern STATE mscp_stu_states[];extern STATE mscp_xfr_states[];extern STATE mscp_repl_states[];extern DMSCP_MEDIA dmscp_media[];extern int dmscp_media_ct;extern int hz;extern int lbolt;extern int wakeup();extern dev_t rootdev;extern dev_t dumpdev;extern struct swdevt swdevt[]; UNITB *mscp_check_sysdev();/**//* * * Name: mscp_init_driver - Initialize class driver * * Abstract: * * Inputs: * * Outputs: * * * Return NONE * Values: *//* TODO (?) Should initial sequence number be randomized? */voidmscp_init_driver(){ register int i; int s; u_short init_seq_no = 1; register CLASSB *clp = &mscp_classb; register CMSB *cmsp = &clp->cmsb; /* Do initialization common to disk and tape class drivers. */ mscp_common_init(); /* Prevent re-entry during initialization */ s = Splscs(); if ( clp->flags.init_ip || clp->flags.init_done ) { ( void )splx( s ); return; } /* Inititialize class block flags */ clp->flags.init_ip = 1; clp->flags.disk = 1; /* Init class driver block listheads */ clp->flink = ( CONNB * )&clp->flink; clp->blink = ( CONNB * )&clp->flink; /* Zero and fill in the embedded connection management * services block (CMSB). */ cmsp->control = mscp_control; cmsp->msg_event = mscp_message; cmsp->dg_event = mscp_datagram; cmsp->lport_name = 0; Zero_scaaddr( cmsp->rport_addr ); cmsp->init_dg_credit = 2; cmsp->min_snd_credit = 2; cmsp->init_rec_credit = 10; ( void )bcopy( "U32_DISK_CL_DRVR", cmsp->lproc_name, NAME_SIZE ); ( void )bcopy( "MSCP$DISK ", cmsp->rproc_name, NAME_SIZE ); ( void )bcopy( " ", cmsp->conn_data, DATA_SIZE ); /* Initialize the unit table and point the class block at it. */ for( i = 0; i < NUNIT; i++ ) mscp_unit_tbl[ i ] = ( UNITB * )NULL; clp->unit_tbl = mscp_unit_tbl; /* Initialize the ULTRIX device disk device name string. */ clp->dev_name = "ra"; /* Initialize recovery state table pointer */ clp->recov_states = mscp_rec_states; /* Start up a 1 second timer for use by connection management and * the resource allocation routines. */ ( void )timeout( mscp_timer, ( caddr_t )clp, hz ); /* Find all the currently known subsystems, start the * connection process (which will complete asynchronously), * restore the entry IPL and exit. */ mscp_system_poll( clp ); ( void )splx( s ); return;}/**//* * * Name: mscp_onlinecm - Format and send an MSCP ONLIN command. * * Abstract: Format and queue an MSCP online command to be sent. * * Inputs: rp Request block pointer. * * Outputs: NONE * * * Return NONE. * Values: */u_longmscp_onlinecm( event, rp ) u_long event; register REQB *rp;{ register MSCP *mp = rp->msgptr; register UNITB *up = rp->unitb; register u_long new_event; /* Format the message buffer as a ONLINE command with the exclusive * access modifier. Update the state and send the message, then exit * to wait for the ONLINE end message to come back. * If excl_acc is specified then set the unit into the exclusive access * pseudo state. The unit will remain in exclusive access mode if the * modifier was previously set. If the exclusive access modifier is not * set and the unit is presently in the exclusive access state the unit * will no longer be in exclusive access mode. */ Init_msg( mp, rp->rspid, up->unit ); mp->mscp_opcode = MSCP_OP_ONLIN; if ( up->flags.excl_acc ) mp->mscp_modifier = MSCP_MD_EXCAC; new_event = mscp_send_msg( rp ); return ( new_event );}/**//* * * Name: mscp_onlineem - process an online end message. * * Abstract: * * Inputs: rp Request block pointer. * * Outputs: NONE * * * Return NONE. * Values: */u_longmscp_onlineem( event, rp ) u_long event; register REQB *rp;{ register MSCP *mp = rp->msgptr; register UNITB *up = rp->unitb; register u_long new_event; u_short em_status = mp->mscp_status & MSCP_ST_MASK; u_short em_subcode = mp->mscp_status >> MSCP_ST_SBBIT; /* Check to see if the online succeeded. */ if( em_status == MSCP_ST_SUCC ) { /* Set a unit flag to remember to bypass BBR processing * if the unit was already online. */ up->flags.alonl = ( em_subcode == MSCP_SC_ALONL ); /* If the unit is formatted for the DEC10/20, it is not * usable. Redispatch to avail the unit. * TODO - Check D0 and D1 of media ID against unitb. */ if( mp->mscp_unt_flgs & MSCP_UF_576 ) { mscp_recycle_rspid( rp ); new_event = EV_ONLERRAVAIL; /* Store the contents of the online end message, recycle the * RSPID, then format and send a get unit status message. */ } else { up->unit_id = *( UNIQ_ID * )mp->mscp_unit_id; up->media_id = mp->mscp_media_id; up->unt_size = mp->mscp_unt_size; up->vol_ser = mp->mscp_vol_ser; up->unt_flgs = mp->mscp_unt_flgs; mscp_recycle_rspid( rp ); Init_msg( mp, rp->rspid, up->unit ); mp->mscp_opcode = MSCP_OP_GTUNT; new_event = mscp_send_msg( rp ); } /* The online command did not succeed. If the error was caused by * a duplicate unit number, print a message on the console. For all * errors, reset online-in-progress and redispatch with an online * complete event. */ } else { if( em_status == MSCP_ST_OFFLN) { switch (em_subcode) { case MSCP_SC_DUPUN: printf( "mscp - Duplicate unit %d detected", up->unit ); printf( " on controller xxx\n"); break; case MSCP_SC_EXUSE: printf( "mscp - Unit %d is exclusive access", up->unit ); printf( "to another host.\n" ); break; } } else if(( em_status == MSCP_ST_AVLBL ) && ( em_subcode == MSCP_SC_ALUSE )) { printf( "mscp - Unit %d is online to another host.\n",up->unit ); } new_event = EV_ONLERROR; } return( new_event );}/**//* * * Name: mscp_onlgtuntem - process GTUNT end message. * * Abstract: * * Inputs: rp Request block pointer. * * Outputs: NONE * * * Return NONE. * Values: */u_long mscp_onlgtuntem( event, rp ) u_long event; register REQB *rp;{ register MSCP *mp = rp->msgptr; register UNITB *up = rp->unitb; register u_long new_event = EV_ONLCOMPLETE; u_short em_status = mp->mscp_status & MSCP_ST_MASK; u_short em_subcode = mp->mscp_status >> MSCP_ST_SBBIT; /* If the Get Unit Status command succeeded, store the unit * status in the unit block. */ if( em_status == MSCP_ST_SUCC ) { Pad_msg( mp, rp->msgsize ); up->mult_unt = mp->mscp_mult_unt; up->unt_flgs = mp->mscp_unt_flgs; up->unit_id = *( UNIQ_ID * )mp->mscp_unit_id; up->media_id = mp->mscp_media_id; up->shdw_unt = mp->mscp_shdw_unt; up->shdw_sts = mp->mscp_shdw_sts; up->track = mp->mscp_track; up->group = mp->mscp_group; up->cylinder = mp->mscp_cylinder; up->unit_svr = mp->mscp_unit_svr; up->unit_hvr = mp->mscp_unit_hvr; up->rct_size = mp->mscp_rct_size; up->rbns = mp->mscp_rbns; up->rct_cpys = mp->mscp_rct_cpys; up->flags.wrtp = (( mp->mscp_unt_flgs & ( MSCP_UF_WRTPH | MSCP_UF_WRTPS | MSCP_UF_WRTPD )) != 0 ); up->flags.rct_pres = ( mp->mscp_rct_cpys != 0 ); up->tot_size = up->unt_size + ( up->rct_size * up->rct_cpys ); /* If BBR is done by the host, the unit is write enabled, and the * unit was not already online when we issued the most recent ONLINE * command, call the BBR code to do ONLINE-time processing.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -