Google
 

Trailing-Edge - PDP-10 Archives - bb-lw55a-bm - galaxy-sources/mtrcfs.mac
There are 8 other files named mtrcfs.mac in the archive. Click here to see a list.
TITLE	MTRCFS - CI/CFS support for MOUNTR
SUBTTL	Preliminaries

;	COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1984, 1988.
;	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 THAT IS NOT SUPPLIED BY DIGITAL.
SUBTTL	Required files 

	SEARCH MTRMAC
	SEARCH MONSYM
	SEARCH MACSYM
	SEARCH ACTSYM
	SEARCH SERCOD
	SEARCH GLXMAC
	SEARCH QSRMAC
	SEARCH ORNMAC
	.REQUIRE SYS:MACREL

	SALL				;Want clean listings

SUBTTL	Version Information

	CFSMAN==:0			;Maintenance edit number
	CFSDEV==:51			;Development edit number
	VERSIN (CFS)			;Generate edit number

IF2,<
	PRINTX [Assembling MTRCFS]
> ;End IF2
	Subttl	Table of Contents

;		     Table of Contents for MTRCFS
;
;				  Section		      Page
;
;
;    1. Revision History . . . . . . . . . . . . . . . . . . .   5
;    2. External Symbols . . . . . . . . . . . . . . . . . . .   6
;    3. Static data  . . . . . . . . . . . . . . . . . . . . .   7
;    4. Port Initialization Routine
;        4.1    Description  . . . . . . . . . . . . . . . . .   8
;        4.2    PRTINI . . . . . . . . . . . . . . . . . . . .   9
;    5. KSPT - Process SET PORT command from OPR . . . . . . .  10
;    6. Exit routines
;        6.1    EXERNR - EXit ERror No RSB . . . . . . . . . .  11
;    7. CIPTON - Process SET CI PORT AVAILABLE . . . . . . . .  12
;    8. Process SET CI PORT UNAVAILABLE
;        8.1    Description  . . . . . . . . . . . . . . . . .  15
;        8.2    CIPTOF - Initial message generation  . . . . .  16
;        8.3    Main loop through all disks  . . . . . . . . .  17
;        8.4    CIPTRE - Clean up and set port unavailable . .  18
;        8.5    DISMNO - Dismount w/o OPR inquire  . . . . . .  19
;        8.6    DSMOPR - Dismount with OPR inquire . . . . . .  20
;        8.7    CIPTDU - Dual ported disk process  . . . . . .  21
;        8.8    CLNREQ - Clean up request after checking OPR r  22
;        8.9    STDUMS - Setup message to resolve dual port  .  23
;        8.10   STREXC - Set structure exclusive with OPR help  24
;        8.11   SETEXC - Set structure exclusive if necessary   25
;    9. CIPTUN - Set disk DDB entry to indicate port operation  26
;   10. PPTRR - Parse OPR response to query  . . . . . . . . .  27
;   11. Channel Routines . . . . . . . . . . . . . . . . . . .  28
;   12. DIAG% Routines . . . . . . . . . . . . . . . . . . . .  29
;   13. Common File System Support
;       13.1    CFSCHK - Check to see whether CFS system . . .  30
SUBTTL 	Revision History

COMMENT \

*****	Release 5.0 -- Begin Development edits *****

1	5.1015		4-mar-83
	Create CFS support module.

2	5.1029		8-june-83
	Add support for setting CI port offline

3	5.1029		8-june-83
	Change references to DV.OFL to DV.UAV & DV.ONL to DV.AVA
to coincide with the changes in ORNMAC

4	5.1029		20-june-83
	Add code changes recommended in code review.

5	5.1030		22-june-83
	Fix code to handle inferior requests for dismount.  The problem was 
that the port rsb was not retained and therefore the request could not be
continued after a dismount.

6	5.1031		29-june-83
	Add CFS support code

7	5.1033		6-july-83
	Add plug for CFSCHK to determine whether CFS system or not.

10	5.1042		30-Sep-83
	Fix code to handle inferior requests for dismount.  The problem was 
that the existing dismount code was not designed to handle an inferior
dismount request.  The return from the dismount was always to the caller,
but in the case of port operation we want to return to scheduler on a
DISMOUNT query and set port code on error or success.  Set SETFLG to zero
if non CFS.  Move some routines to MOUNTR.  Add code to set the disk
unavailable/available.

11	5.1044		14-Oct-83
	In routine SETPFP, print the correct message in relationship to 
AVAILABLE/UNAVAILAVLE when we are debugging.  Always release the 
dismount RSB after successfully completing a dismount.  Clear SETFLG
at end of port operation.  Make sure AC0 is not touch accidentally.

12	5.1045		19-Oct-83
	In CIPTAV we delete a disk entry by calling DSFDEL, however the routine
is called within a literal and does not have code handle a +2 return.
Therefore on a +2 return MOUNTR starts to execute data in the literal pool.

13	5.1057		14-Nov-83
	Add two line of code to set a structure unavailable after it has been 
dismounted via setting the port unavailable.

14	5.1059		23-Nov-83
	Add a new routine, CIPTDU, to check for dual ported disk drives and
tell the operator to set that dual ported drive single ported to a system.

15	5.1060		28-Nov-83
	SETFLG is globally defined and does not always pertain to a particular
port operation.  Set a bit, R%REP, in RSBIFL(RSB) to indicate a FORCE action
to a port operation. 

16	5.1061		29-Nov-83
	After setting the port unavailable, add a port entry to the devices-
status data dase to maintain a port's exclusivity across reloads.

17	5.1062		30-Nov-83
	Make DIAGER an internal routine.

20	5.1066		9-Dec-83
	Lots of changes:
1.  Clean up: Add table of contents; Add an SALL instruction to
suppress macro expansions to make easier to understand listings.
Add lots of comments to clearify code.
2.  Eliminate some 2 and 3 line error routines that are only used once
and place them in inline code as literals to make things clearer.
3.  Make routine CIPT a continuation of the routine KSPT since KSPT always
jumps there anyway.
4.  Eliminate some of the logic in CIPTON.  If any disk drive is unavailable
due to port operation, set it back to available.  (This assumes only
one CI and that is the only PORT that can set disk drives unavailable.)
5.  Eliminate routine CIPTDN.  Both the CIPTON and CIPTOF should exit through
CIPTEX.
6.  Make routines CIPTR and KSCH local routines since noone else uses them.
7.  Change messages for setting port unavailable.

21	5.1076		4-Feb-84
	Lots of changes:
1.  Check for port existance on SET PORT command
2.  Tell of disk drives returned when setting port available.
3.  When checking all disk drives, base the search on disk DDBs
4.  Fix all references to DDB to use new DDB routines.
5.  Add some references to the new $STOP macro to better describe cause for
    failure causing halt.
6.  Make the messages output more reasonable and consistant.
7.  Create entirely new port initialization routine PRTINI.

22	5.1098		14-Feb-84
	Make sure we have the correct RSB when SETPT is called.  Loop through
DDB instead of DSK when printing disk information relating to port 
operation.

23	5.1114		12-Mar-84
	Number of changes:
1.  Add the smarts to correctly determine if we have a CI port.
2.  Add setting structures exclusive if setting port unavailable in CFS.
3.  Make some general purpose exit routines to have better control of
exit conditions.
4.  Rework main loop of setting CI port unavailable.

24	5.1115		12-Mar-84
	Add check to set CFSB.  Create routine CFSCHK to return if
another CFS node seen (indicating part of CFS configuration).

25	5.1126		2-Apr-84
	Add code to set a structure shared when setting the port available.

26	5.1153		27-July-84
	If the port operation is aborted, set the last disk drive and its 
mounted structure back to its previous status based the DDB.

27	5.1166		15-Oct-84
	Clear RSBDSK as part of the set up procedures for a port operation 
because that location might contain previous data.  In routine EXEARB, make 
sure the DDB and DSK pointer in RSBDSK is not zero, before we try to do some 
clean up.

30	5.1188		7-Dec-84
	Add message to ask whether the system setting the CI available is part
of a single CI system.  If yes do DIAG JSYS and reset disk drives, if no don't
do DIAG JSYS but do the latter.

31	5.1194		14-Jan-85
	In routine DISMNO, clear AC 4 before the CALL MATCHS.

32	5.1195		22-Jan-84
	Change message in edit 30.  If yes skip DIAG else do DIAG and reset the
isk drives.
*****	Release 5.0 -- begin maintenance edits	*****
40	Increment maintenance edit level for version 5 of GALAXY.

*****	Release 6.0 -- begin development edits	*****

50	6.1037		26-Oct-87
	Move sources from G5: to G6:

51	6.1225		8-Mar-88
	Update copyright notice.

\	;End of Revision History
SUBTTL	External Symbols

EXTERN AREQ,ARET
EXTERN SAVEQR,SAVETR,STAKTR
EXTERN IOXCTR
EXTERN QSCNIR
EXTERN TMCT0
EXTERN ANY,PRTRSB
EXTERN STRDM2,STRDMS
EXTERN DSPFLG,DSKDSP

;  Externals used from MTRDDB

EXTERNAL DSFCRE		;Create a DDB entry
EXTERNAL DSFGET		;Given pointer, get DDB entry
EXTERNAL DSFLOC		;Given spc. locate DDB entry
EXTERNAL DSFUDE		;Given pointer and new entry in DSFE, update it
EXTERNAL DSFNUP,DSFYUP	;No/Yes update disk on updates to DDB
EXTERNAL DSFGNX		;Get next DDB entry of specified type

EXTERNAL DSFE		;Globally used structure to hold DDB

EXTERN STOP,STOPNW	;Stop processing routines
EXTERN PSDR,PRQABT,WOMDAV
EXTERNAL BTACKT,BTNFO,BTWTO

EXTERNAL PORTST		;Port test variable used by MOUNTR to determine state
			;of CI port
EXTERNAL DSMHDR		;Dismount TMCT style header
EXTERNAL DDSCIH		;Update all disks routine
EXTERNAL STRREF		;Routine to process operator refusal
EXTERNAL LSTERR		;Last error word
EXTERNAL CFSB		;CFS Built flag
EXTERNAL STSTR,NEWSTA	;Restore structure status
SUBTTL Static data

UNLNOT:	ASCIZ/Port Unavailable Procedure Notice/
AVLNOT:	ASCIZ/Port Available Procedure Notice/
SUBTTL Modifyable data area

DIAGLN==:3
DIAGBK: BLOCK DIAGLN		;Argument block for diag 
CNFBLK:	BLOCK .CFISO+1		;Argument block for CNFIG% JSYS

;Equates

;DIAG

.DGENB==111		;Disable/enable port function - not yet in MONSYM

.DSDUL==:5		;A set port switch RSB type.
.DSEXC==:6		;An exclusive RSB type
SUBTTL Port Initialization Routine -- Description

COMMENT %

The flow of the port initialization routine goes something like this:

Check for port entry in DDB
If entry exists then
begin
    If available port then
    begin
	for all disk entries do
	begin
	    get entry
	    clear unavailable due to port operation bit
	end
    else
	perform diag to set port unavailable
end
else		;If port entry does not exist
begin
    determine port existance
    If port exists then
    begin
	create port entry as available
	notify operator
    end
end

Apologies to formal language enthusiasts...

NOTE:  If port ever existed, continue to allow unavailable in case CI has
been on this system and is currently just busted or missing.  In this case,
allowing the use of dual ported drives could be disasterous.
% ; End comment
SUBTTL Port Initialization Routine -- PRTINI

PRTINI:: SETZM PRTRSB		;We are not in a port unavailable procedure
	SETZM PORTST		;Default port to available and exists
	SETZM CFSB		;Default to not CFS built
	MOVEI T1,.CFINF		;Get the function code
	MOVEI T2,.CFISO+1	;Get the length
	MOVEM T2,CNFBLK+.CFLEN	;Set it in argument block
	MOVEI T2,CNFBLK		;Get address of argument blok
	CNFIG%			;Get the configuration information
	  ERJMP PRTIN0		;Go to no port
	MOVE T1,CNFBLK+.CFISO	;Get the software options
	TXNE T1,CF%CFS		;Do we have CFS built?
	SETOM CFSB		;Yes, set the flag
	MOVE T1,CNFBLK+.CFIHO	;Get the bits
	TXNN T1,CF%CI		;Do we have a CI?
PRTIN0:	SETOM PORTST		;Set no port

;  Check for port entry in DDB

	MOVEI T1,.DVPRT		;Get the port type
	MOVEM T1,DSFE+DSFTYP	;Save it
	SETZ T1,		;Say we have no entries
	CALL DSFGNX		;Get the next port entry
	  JRST PRTIN5		;Go check for a port on the system
	SKIPN PORTST		;Do we have a port?
	CALL [SETOM DSFE+DSFPNT	;Say we have a port
	      CALL DSFUDE	;Update things to say so
	      $STOP <Can't update previously known port entry>
	      RET]

;  Is port to be available or unavailable?

	MOVE T2,DSFE+DSFFLG	;Get the flag word
	TXNE T2,DSF%AV		;Is the port available?
	JRST PRTIN3		;No, go do the unavailable stuff
	SETZM PORTST		;Set port available

;  Port is available.  Want to clear port unavailable due to port operation
;  flag from all disk entries.

	MOVEI T1,.DVDSK		;Get the disk type
	MOVEM T1,DSFE+DSFTYP	;Set it as type
	SETZ T1,		;Go for the first one

;  Loop on all disk entries

PRTIN1:	CALL DSFGNX		;Get the next entry
	JRST PRTIN9		;Must be done, go to the end

	MOVE T2,DSFE+DSFFLG	;Get the flag word
	TXZN T2,DSF%PO		;Clear the bit if needed
	JRST PRTIN1		;If not needed, go for another

	MOVEM T2,DSFE+DSFFLG	;Otherwise set the bit
	CALL DSFUDE		;Update the entry
	  CALL STOP
	JRST PRTIN1		;Go for another

;  End of loop
;  Do the port unavailable stuff
;  Don't need to set DSF%PO in disk DDB entries; should already be done

PRTIN3:	MOVEI T1,1		;Get one
	MOVEM T1,PORTST		;Set it as unavailable port
	MOVE T1,[-DIAGLN,,DIAGBK] ;Size ,, block address
	MOVEI T2,.DGENB		;Get function number
	MOVEM T2,DIAGBK		;Store it in block
	MOVE T2,DSFE+DSFSPC	;Get channel number
	MOVEM T2,DIAGBK+1	;Store it in block
	SETZM DIAGBK+2		;Assume setting disable
	SKIPN TSTF		;Are we testing?
	DIAG			;No, do the real thing
	 ERJMPR [TMCT <%IPort operation unsuccessful%_DIAG%% failure%_%J>
		 JRST PRTIN4]	;Go to send it
	TMCT <%IPort set unavailable>
PRTIN4:	MOVEI T3,[ASCIZ/Port Operation Completed/]
	CALL BTWTO
	JRST PRTIN9		;Go to finish

;  Check for a port on the system

PRTIN5:	SKIPE PORTST		;Do we have the port
	JRST PRTIN9		;No, nothing more to do

;  Create port entry as available

	MOVEI T1,CIPORT		;Get the channel number for port
	MOVEM T1,DSFE+DSFSPC	;And save it
	SETZM DSFE+DSFFLG	;Set the defaults
	SETO T1,		;Device exists but no status block
	MOVEM T1,DSFE+DSFPNT	;Use that for pointer
	CALL DSFCRE		;Create entry
	  JFCL			;Shouldn't happen

;  Tell operator entry added

	TMCT <%IPort set available>
	MOVEI T3,[ASCIZ/Device added to Disk Data Base/]
	CALL BTWTO

;	JRST PRTIN9		;Don't need to jump, already there
	
PRTIN9: RET			;And done
SUBTTL KSPT - Process SET PORT command from OPR

KSPT::	SKIPGE PORTST		;Do we have a port?
	JRST [TMCT <%ICI PORT does not exist> ;No
	      JRST EXERNR]	;Go output the error
	SKIPE PRTRSB		;Are we already in a port operation?
	JRST [TMCT <%IAlready processing CI port operation>
	      JRST EXERNR]	;Go output the error

	TXO F,PORTF		;Port operation in process
	MOVEI T1,.PTSET		;Port type
	CALL OPRSB##		;Get a status block for request
	 JRST [TMCT <%ISET PORT request denied%
Insufficient MOUNTR resources.%
Try again later.>
	       JRST EXERNR]
	MOVEM RSB,PRTRSB	;Save the RSB and say we are processing
	MOVE T1,RBUF+6		;Get flag/channel word
	MOVEM T1,RSBPRT(RSB)	;Save into the status block

	LOAD T2,DV.CHN,RSBPRT(RSB) ;Get unit number
	CAIE T2,-1		;Channel specified? halfword field is
				;-1 if not
	JRST [TMCT<%ISET PORT command only supported for CI port> ;Yes
	      JRST EXERRB]	;Go output the error

	TXNN T1,DV.CI		;CI channel specified?
	JRST [TMCT<%IUnknown Port type.%_Only CI ports are supported>
	      JRST EXERRB]	;Go output the error

;  Here we know the command calls for setting status of the CI port

	SETZM RSBDSK(RSB)	;Clear any invalid information from previous
	MOVX T1,R%PRT		;Indicate port operation
	IORM T1,RSBIFL(RSB)	;Set it
	MOVEI T1,CIPORT		;Get Channel number
	HRRM T1,RSBPRT(RSB)	;Save it
	HLL T2,RSBPRT(RSB)	;Get flags from status block
	TXNN T2,DV.UAV		;available or unavailable?
	JRST [SKIPE PORTST	;Available... is it already available?
	      JRST CIPTON	;No, so go do it
	      TMCT <%ICI Port already set available> ;Error message
	      JRST EXERRB]	;Output the error
	SKIPG PORTST		;Is it already unavailable?
	JRST CIPTOF		;Set unavailable (enable diag operations)
	TMCT <%ICI Port already set unavailable> ;Error message
	JRST EXERRB		;Go send message and quit
SUBTTL Exit routines -- EXERNR - EXit ERror No RSB

EXERNR:	MOVEI T3,PTEMSG		;Get header
	CALL BTACKT		;Tell of problem	
	RET			;Return, No RSB to delete

SUBTTL Exit routines -- EXERRB - EXit with ERror and RSB

EXERRB:	MOVEI T3,PTEMSG		;Get error header

;  continue with EXNERB below

SUBTTL Exit routines -- EXNERB - EXit No Error and with RSB, header set

EXNERB:	CALL BTACKT		;Tell of the problem
	TXZ F,PORTF		;Not in port operation
	MOVE RSB,PRTRSB		;Get the port RSB for sure
	SETZM PRTRSB		;And clear it, no longer processing port op.
	ABTREQ (ABRTNR)		;Clear up RSB
	CALL DDSCIH		;Update things
	RET			;And done

SUBTTL Exit routines -- EXOARB - EXit with Operator Abort and RSB

EXOARB:	TMCT <%IAborted by operator>

;  continue with EXEARB below

SUBTTL Exit routines -- EXEARB - EXit Error Abort with RSB


EXEARB:	

;  Clean up disk and structure

	MOVE RSB,PRTRSB		;Get the port RSB
	HLRZ T1,RSBDSK(RSB)	;Get the DDB address
	JUMPE T1,EXABOR		;No DDB, must not have started P.O. yet
	CALL DSFGET		;Get the disk entry
	 $STOP <Disk drive went away while attempting to clean up abort port operation>			;No disk something is wrong
	SETZ T2,		;Clear the unavailable due to P.O bit
	STOR T2,DSF%PO,DSFE+DSFFLG ;store it in the DDB
	CALL DSFUDE		;Update entry
	 $STOP <Bad pointer or bad data to DSFUDE..while aborting P.O.>
	MOVE DSK,DSFE+DSFPNT	;Get DSK address
	MOVE T1,DSKFLG(DSK)	;Get the disk flag
	TXNN T1,MS%MNT		;Is it mounted?
	JRST EXABOR		;No, all done	

;  Now for the structure

	HLRZ STR,DSKP2(DSK) 	;Get the SSB
	MOVE T1,STRPNT(STR)	;Get the DDB pointer 
	CALL DSFGET		;Get the entry
	 $STOP <Bad DDB pointer to str entry>
	CALL NEWSTA		;Get the status
	 JRST EXABOR		;Not there, all done
	CALL STSTR		;Set it
	 JFCL

EXABOR:	MOVEI T3,[ASCIZ/Port Unavailable Procedure Termination/]
	JRST EXNERB		;Continue with procedure above

SUBTTL Exit routines -- EXRSNR - EXit for ReSponse No RSP processing

EXRSNR:	PUSH P,T1		;Save the return routine address
	CALL BTNFO		;Set for no formatting
	TXZ F,PORTF		;Clear port function flag
	MOVEI T2,RSBWTB(RSB)	;Get the WTB address
	MOVEI T3,UNLNOT		;Get address of notice
	POP P,T1		;Get back return routine address
	CALLRET BTWTOR##	;Send wtor

PTEMSG:	ASCIZ/Problem Setting Port/
SUBTTL CIPTON - Process SET CI PORT AVAILABLE
	
;  JRSTed to only by KSPT

;  AC usage:
;	Q1 /	 0 if diag successful
;		-1 if diag found no CI
;	Q2 /	 0 if no disks changed
;		-1 if disks set available

CIPTON:	TMCT <%IIs there another TOPS-20 system currently running on the CI?
'RESPOND <number> Yes or No'%_>
	MOVEI T1,CIPTAV		;Get return address
	MOVEI T2,RSBWTB(RSB)	;Get the WTB address
	MOVEI T3,AVLNOT		;Get address of notice
	CALLRET BTWTOR##	;Send wtor
	
CIPTAV:MOVEI RSB,-RSBWTB(T2)	;Load RSB ac
	CALL PSDR##		;Parse answer
	 JRST CIPTON 		;Error, try again
	JUMPE T1,[TMCT <%ICI port will not be in use until system is reloaded%_>				;Yes another TOPS-20 system running on CI
		  MOVEI T3,AVLNOT ;Get address of notice
		  CALL BTWTO##  ;Tell the operator
		  JRST CIPTO2]	;Skip DIAG

	SETZ Q1,		;Assume things will be ok
	CALL SETPT		;Do diag
	SKIPA			;Error
	JRST CIPTO2		;No error, continue on

;  Had an error.  If CI does not exist, then quit

	MOVEI T1,.FHSLF		;Get my fork
	GETER			;Get the error
	ERJMP CIPTO1		;Real error
	HRRZ T2,T2		;Get only the error
	CAIE T2,DIAG14		;Is it does not exist?
CIPTO1:	JRST [TMCT <%IPort available operation unsuccessful%_DIAG%% failure%_%J>
	      TMCT <%Disks have not been set back to available%_>
	      JRST EXERRB]	;Go to error exit
	SETO Q1,		;Mark things that DIAG doesn't count
				;Still want to clean up disks if possible

CIPTO2:	SETZ Q2,		;No disks found yet
	TMCT <%IThe following disk drive(s) have been returned to available:%_>
	CALL DSFNUP		;Hold up on updating disk data base

;  Loop on all disk drives to fix unavailable due to port operation
;  Assumptions made for this code:
;  o  There can be only one CI per system.
;  o  Only CI can make a disk unavailable due to port operation.

	MOVEI T1,.DVDSK		;The type to look at is disks
	MOVEM T1,DSFE+DSFTYP	;Set it as type to look for
	SETZ T1,		;Set up for first disk
;  Begin loop

CIPTO3:	CALL DSFGNX		;Get next disk
	  JRST CIPTO5		;Go clean up
	MOVEM T1,Q3		;Save the next disk DDB pointer 
	MOVE T2,DSFE+DSFFLG	;Get the flags
	TXZN T2,DSF%PO		;Unavailable due to port operation?
	JRST [CALL SETSHR	;No, check to see if it should be set shared
	      JRST CIPTBK]	;Go get next dsk entry

	MOVEM T2,DSFE+DSFFLG	;Yes, already cleared bit, save it back
	TXNN T2,DSF%AV		;Is the disk available now?
	JRST [MOVE T2,DSFE+DSFSPC ;Yes, get the CKU
	      TMCT <%2K set available%_> ;Message for this disk
	      SETO Q2,		;Found a disk to set available!
	      JRST CIPTO4]	;Continue
CIPTO4:	CALL DSFUDE		;Update the entry
	  CALL STOP		;Should not happen!
CIPTBK:	MOVE T1,Q3		;Get the next disk pointer 
	MOVEI T2,.DVDSK		;The type to look at is disks
	MOVEM T2,DSFE+DSFTYP	;Set it as type to look for
	JRST CIPTO3		;Go get next dsk entry

;  End of loop

;  Send message to operator informing of successful completion

CIPTO5:	SETZM PORTST		;Say things are available
	MOVEI T1,.DVPRT		;Get the port type
	MOVEM T1,DSFE+DSFTYP	;Save it
	SETZ T1,		;Say we have no entries
	CALL DSFGNX		;Get the next port entry
	 JRST CIPTO6		;Don't care if not found
	SETZRO DSF%AV,DSFE+DSFFLG ;Clear unavailable bit
	CALL DSFUDE		;Update the entry
	 JFCL			;Really don't care at this point

CIPTO6:	CALL DSFYUP		;Reenable updating DDB.
	SKIPN Q2		;Did we have any disk status changes?
JRST [TMCT <%INo disk drives set available%_> ;No.
	      JRST CIPTO7]	;Continue on

CIPTO7:	SKIPE Q1		;Did we really set the port?
	JRST [TMCT <Port not found but status set to available>
	      JRST CIPTO8]	;Continue on
	TMCT <Port set available> ;Completion message for available

CIPTO8:	MOVEI T3,[ASCIZ/Port Available Operation Completed/]
	JRST EXNERB		;Tell operator and exit
;SETSHR - Set a structure shared due to port available
;Accepts - DSFE for disk entry might not be perserved
;return  - +1 always

SETSHR:	MOVE T1,DSFE+DSFPNT	;Get the disk pointer
	MOVE T2,DSKFLG(T1)	;Get the disk status
	TXNN T2,MS%MNT		;Do we have a structure mounted on this disk
	JRST SETSH2		;No, go back to loop

;  Get the SSB

	HLRZ T2,DSKP2(T1) 	;Get the SSB
	SKIPN T2		;Do we have a valid SSB?
	 $STOP <STRUCTURE IS MOUNTED ON DISK BUT NO SSB>
	MOVE T1,STRFL1(T2)	;Get the status
	TXNN T1,STR%EP		;Is it already shared
	JRST SETSH2		;Yes, all done 
	SETZRO STR%EP,STRFL1(T2) ;No, clear the exclusive due to P. O. bit
	MOVE T1,STRPNT(T2)	;Get the structure DDB pointer 
	CALL DSFGET		;Get the entry
	 $STOP <CAN'T GET STRUCTURE DDB WHILE SETTING STR SHARED DURING P.O>
	MOVE T1,DSFE+DSFFLG	;Get the structure status flag
	TXNE T1,DSF%EX		;Is it exclusive?
	JRST SETSH2		;Yes, go back to loop

;  Have to set the structure shared

	MOVEI T1,DSFE+DSFSPC	;Get address of alias
	MOVE T2,[POINT 7,MSTAL]	;Destination of ascii alias
	CALL SIXSEV		;Translate it
	MOVE T3,[POINT 7,MSTAL]	;Need pointer again
	SETZ T4,		;Shared
	MOVE T1,[2,,.MSCSM]	;length 2,,function
	MOVEI T2,T3		;Set up arg block address
	MSTR			;Try to set exclusive
	  ERJMP [MOVEI T1,.FHSLF ;Didn't work, get self
		 GETER		;Get last error
		 HRRZ T1,T2	;Get just error
		 CAIN T1,MSTX45 ;CFS error?
		 JRST SETSH2	;Yes, just return to loop
		 MOVE T2,STRALI(STR) ;Error, get structure name
		 TMCT <Set Structure Shared failed during procedure%_>
		 TMCT <Problem with structure %2S:%_Error -%1J%_%U>
		 JRST SETSH2]	;Return back to loop with error

	MOVE T1,DSFE+DSFSPC	;Get alias structure name
	TMCT <Structure %1S set shared due to port available operation%_>

SETSH2:	RET			;Go process the next disk
SUBTTL Process SET CI PORT UNAVAILABLE -- Description

COMMENT %

The flow of port unavailabe goes something like this:

Send message to operator describing the impact.
If abort then quit
START LOOP::
while more disks do
begin
    If on channel 7 then
    begin
	Try to dismount without operator intervention
	If not successful then exit loop and go process with intervention.
    end
    else
    if CFS then
    begin
	If dual ported then
	begin
	    if not port force procedure then exit loop and
				 process dual port (need intervnt)
	    dismount structure ignoring any need for operator assist
	end
	If mounted and structure not exclusive due to port operation then
	begin
	    try to set exclusive
	    if not successful then exit loop and set exclusive with intervent.
	    set structure exclusive due to port operation
	end (of if CFS)
end (of while more disks)

All exit loops return by reinitializing and starting the loop again at
START LOOP::

% ; End of comment
SUBTTL Process SET CI PORT UNAVAILABLE -- CIPTOF - Initial message generation

;  JRSTed to only KSPT

CIPTOF:	CALL DDSCIH		;Go update disks
	CALL KSCH		;Show structures on channel
	MOVEI T1,CIPTR		;Address of reply 
	JRST EXRSNR		;Go to exit with eventual return

;  Here on operator reply to CI port unavailable procedure message

;  Reentry point
CIPTR:	TXO F,PORTF		;Set port function flag
	MOVEI RSB,-RSBWTB(T2)	;Load RSB ac
	CALL PPTRR		;Parse answer
	 JRST CIPTOF		;Error, try again
	JUMPL T1,EXOARB		;Go do it if operator wants to abort
	SKIPE TSTF##		;If private mountr
	JRST CIPTRE		;Jump to diag call

;  Continued on next page
SUBTTL Process SET CI PORT UNAVAILABLE -- Main loop through all disks

;  continued from previous page
CIPTR0:	SETZ T1,		;Want to start at the beginning
	SKIPA			;Don't want to overwrite

;  Beginning of the loop.  AC RSB should contain the port RSB

CIPTR1:	HLRZ T1,RSBDSK(RSB)	;Get the address of last examined DDB
	MOVEI T2,.DVDSK		;Get the disk type
	MOVEM T2,DSFE+DSFTYP	;Save the type
	CALL DSFGNX		;Go get the next one
	 JRST CIPTRE		;No more, must be done
	HRLM T1,RSBDSK(RSB)	;Save where we now are
	MOVE T1,DSFE+DSFFLG	;Get the flag word
	SKIPLE DSK,DSFE+DSFPNT	;Does this one point nowhere?
	TXNE T1,DSF%PO		;No, is it already unavailable due to Port op?
	JRST CIPTR1		;Yes, go for next one

	LDB T1,[POINT 12,DSKCKU(DSK),11] ;Get channel number
	HRRZ T2,RSBPRT(RSB)	;Get channel number from port request
	CAME T1,T2		;Is it the requested channel?
	JRST CIPTR2		;No, go do other checks.

;  Here when disk is on channel and we want to dismount

	CALL DISMNO		;Go try to dismount structure without operator
	 JRST [SKIPN RSB	;No such luck, abort?
	       JRST EXEARB	;Yes, go finish up
	       JRST DSMOPR]	;Otherwise, leave loop for opr inquire
	MOVE RSB,PRTRSB		;Restore port RSB
	JRST CIPTR1		;Go for next entry in loop

;  Here for not channel 7 checks.
;  First do dual port check

CIPTR2:	SKIPN CFSB		;Are we CFS?
	JRST CIPTR1		;No, no further checks needed, go for next one

	MOVE T1,DSKFLG(DSK)	;Get status
	TXNN T1,MS%2PT		;Is is dual ported?
	JRST CIPTR3		;No, go do exclusive check
	MOVE T1,RSBIFL(RSB)	;Get the flags
	TXNN T1,R%REP		;Is it force?
	JRST CIPTDU		;No, leave loop for opr inquire
	CALL DISMNO		;Dismount and set disk unavailable
	 JRST [SKIPN RSB	;Dismount must succeed!
	       JRST EXEARB	;Known abort
	       ABTREQ (ABRTNR)	;Clear up RSB
	       JRST EXEARB]	;And abort
	MOVE RSB,PRTRSB		;Restore port RSB
	JRST CIPTR1		;Go for next entry in loop

;  Set structure exclusive.

CIPTR3:	CALL SETEXC		;Try to set exclusive
	 JRST [CAIN T1,MSTX45	;Is problem simply due to CFS?
	       JRST STREXC	;Yes, go try other
	       JRST EXEARB]	;Error abort		 
	JRST CIPTR1		;Everything OK.  Continue loop

;  End of loop, RSB must be that of port operation

;  Here to reenter the loop

CIPTR9:	CALL DDSCIH		;Go update things if needed
	MOVE RSB,PRTRSB		;Get back the port RSB
	JRST CIPTR0		;Go back to the beginning of the loop
SUBTTL Process SET CI PORT UNAVAILABLE -- CIPTRE - Clean up and set port unavailable

CIPTRE:	CALL SETPT		;Do diag
	JRST [TMCT <%ICI Port unavailable operation unsuccessful%_DIAG%% failure%_%J>
	      JRST EXERRB]	;Go finish up as error
	MOVEI T1,.DVPRT		;Get the port type
	MOVEM T1,DSFE+DSFTYP	;Place it in the type word
	HRRZ T1,RSBPRT(RSB)	;Get the channel number
	MOVEM T1,DSFE+DSFSPC	;Place it in the spec. word
	CALL DSFLOC		;Get the entry
	  CALL STOP		;Should not happen
	MOVEI T2,1		;Say unavailable due to port unavailabilty
	STOR T2,DSF%PO,DSFE+DSFFLG ; store it
	CALL DSFUDE		;Put it back on disk
	  $STOP <Previously legit DDB pointer failed to update entry correctly>
	MOVEI T1,1		;Get one
	MOVEM T1,PORTST		;Set it
	TMCT <%IPort set unavailable>
	MOVEI T3,[ASCIZ/Port Unavailable Operation Completed/]
	JRST EXNERB		;Go send the message and clean up
SUBTTL Process SET CI PORT UNAVAILABLE -- DISMNO - Dismount w/o OPR inquire

;  This routine called from the unavailable loop will try to dismount the
;  structure without operator intervention.  It includes setting the disk drive
;  unavailable, building an RSB for the dismount request if necessary,
;  checking to see if dismount possible and doing so if so.  If the
;  structure is dismounted, then release RSB.

;  Returns: +1 if not successful
;	    RSB / 0 if an error occurs that implies abort
;	    RSB / block for dismount request that needs to follow
;	    +2 if successful

DISMNO:	CALL CIPTUN		;Set disk unav via port operation
	MOVE T1,DSKFLG(DSK)	;Get status
	TXNN T1,MS%MNT		;Is it mounted?
	JRST DISM.9		;No, go for successful return

;  Get an RSB for the dismount request

	MOVEI T1,.DSMST		;Set up a dismount request
	CALL OPRSB##
 	 JRST [TMCT <%IFailed to acquire RSB for dismount procedure>
	       JRST DISM.7]		;Return bad

;  Complete building RSB for dismount request

	MOVE T1,PRTRSB		;Get port RSB
	MOVEM T1,RSBSUP(RSB)	;Save it in DSK RSB 	
	MOVX T1,R%DSM		;Get dismount flag
	IORM T1,RSBIFL(RSB)	;And set into rsb
	SETZM RSBSTN(RSB)	;Zero structure name for matchs
	MOVEI T1,RST.WM
	STOR T1,RSBSTE		;Set state to waiting for dismount
	MOVE T1,RSBSTA(RSB)	;Get structure alias
	MOVE T2,RSBSTN(RSB)	;Get structure name
	SETZ T4,		;No structure unique code 
	CALL MATCHS##		;Match request to structure
	JRST DISM.8		;No match, clean up RSB and return OK
				;  Should we do more for this error?

	SKIPG STR		;Is structure mounted?
	JRST DISM.8		;No, clean up RSB and return OK

;  Now do the dismount

	STOR STR,RSBSS		;Store the structure addr into rsb
	MOVEI T1,RSBSTA(RSB)	;Dismount it
	MOVE T2,[POINT 7,MSTAL##]	
	CALL SIXSEV##
	CALL STRSET##		;Set up for dismount
	JRST [SKIPE LSTERR	;Something, any error?
	      JRST DISM.6	;Yes, do the error processing
	      MOVE T1,PRTRSB	;No error, must think we need operator help
	      MOVE T1,RSBIFL(T1) ;Get the flags
	      TXNN T1,R%REP	;Is this a force?
	      RET		;No, just need operator help
	      JRST DISM.5]	;Yes, dismount anyway

DISM.5:	CALL STRDMS##		;Dismount str without operator help
	JRST DISM.6		;Problem
	JRST DISM.8		;Success, go finish

DISM.6:	CALL DISMER		;Generate dismount error message

DISM.7:	SETZ RSB,		;Set the error
	RET			;And return error

DISM.8: ABTREQ (ABRTNR)		;Mark RSB deleted for no reason
	CALL PRQABT		;Get rid of this dismount RSB

DISM.9:	RETSKP

SUBTTL Process SET CI PORT UNAVAILABLE -- DISMER - Generate dismount error message
DISMER:	ABTREQ (LSTERR,ABT%IN)	;Didn't work, set error
	MOVE T1,STRNAM(STR)	;Get the structure name
	MOVE T2,STRALI(STR)	;Get the alias
	TMCT <%IDismount structure failed during procedure%_>
	TMCT <Problem with structure %1S: (Alias %2:)%_Error -%J%_%U>
	CALL PRQABT		;Get rid of this dismount RSB
	RET
SUBTTL Process SET CI PORT UNAVAILABLE -- DSMOPR - Dismount with OPR inquire

DSMOPR:	MOVEI T1,DSMRPL		;Get end-action address
	MOVE T2,STRALI(STR)	;Get alias
	MOVE T3,STRNAM(STR)	;Get name
	TMCTI <DSMHDR>		;Build message based on dismount header
	JRST EXRSNR		;Send it and wait for reply

;  Here on operator reply to dismount request

;  Reentry point
DSMRPL:	TXO F,PORTF		;Set we are in port operation
	MOVEI RSB,-RSBWTB(T2)	;Load rsb ac
	LOAD STR,RSBSS		;Get structure status block again
	CALL PSDR##		;Parse operator response
	 JRST DSMOPR		;Bad response, try it again
	JUMPE T1,DSMR.1		;Skip this if yes

;  Operator refuses to dismount

	CALL STRREF		;Process refusal
	CALL [ABTREQ(ABRTNR)	;Get rid of RSB
	      RET]		;Message already gen'd by STRREF
	JRST EXOARB		;Exit with operator abort

;  Operator ok'd dismount

DSMR.1:	CALL STRDM2##		;Set str unavailable
	SKIPA			;Can not set str unavailable
	CALL STRDMS		;Go do the dismount
	JRST [CALL DISMER	;Can't, go process error and clean things up
	      JRST EXEARB]	;Process the error and quit
	ABTREQ(ABRTNR)		;Clear up RSB
	CALL PRQABT		;And release
	JRST CIPTR9		;Go begin main loop again
SUBTTL Process SET CI PORT UNAVAILABLE -- CIPTDU - Dual ported disk process

;  Disk is dual ported.  Need to setup and ask the operator to set it single.

CIPTDU:	HRRM DSK,RSBDSK(RSB)	;Save dsk/loop counter
	MOVEI T1,.DSDUL		;Set up a switch request
	CALL OPRSB##
	 JRST [TMCT <%IFailed to acquire RSB for dual port procedure>
	       JRST EXEARB]	;Error abort
	MOVE T1,PRTRSB		;Get port RSB
	MOVEM T1,RSBSUP(RSB)	;Save it in switch RSB 
CIPTD0:	TMCT <%I>		;Initialize the message

CIPTD1:	CALL STDUMS		;Set up the meesage to be asked
	MOVEI T1,CIPTD2		;Address of reply
	JRST EXRSNR		;Go send message and wait for reply

;  Here when the operator has responded.  Check his answer.

;  Reentry point
CIPTD2:	TXO F,PORTF		;Set port function flag
	MOVEI RSB,-RSBWTB(T2)	;Load RSB ac
	CALL PPTRR		;Parse answer
	 JRST CIPTD0 		;Error, try again
	MOVE T2,PRTRSB		;Get address of port RSB
	HRRZ DSK,RSBDSK(T2)	;Get DSB address
	JUMPE T1,[MOVE T2,DSKFLG(DSK) ;Get status of disk
		  TXNN T2,MS%2PT ;Is operator fibbing, still dual ported?
		  JRST CIPTD3	;No, continue on
		  TMCT <%IDisk drive not correctly ported.%_>
		  JRST CIPTD1]	;Go try again

CIPTD3: JRST CLNREQ		;Go clean up the request
SUBTTL Process SET CI PORT UNAVAILABLE -- CLNREQ - Clean up request after checking OPR reply

;  This routine is JRSTed to by either the dual ported code or by structure
;  exclusive code.  It cleans up the RSB.  If it was proceed, it was OK
;  (assumed to be so to come here) and returns to the loop.  If it was abort,
;  it goes to the operator abort code.  If it was force, it then tries to
;  dismount the structure.

;  Accepts: T1 / Result from PPTRR
;  Returns:  Either jumps back to beginning of loop or aborts due to error

CLNREQ:	PUSH P,T1		;Save the result of PPTRR for a min
	ABTREQ(ABRTNR)		;Get rid of RSB
	CALL PRQABT		;Clear up RSB
	POP P,T1		;Get back result

	JUMPE T1,CLNRE9		;Go back and proceed OK if operator did OK
	JUMPL T1,EXOARB		;Abort if operator did that

;  Here if force.  Do dismount if needed and set unavailable

	CALL DISMNO		;Try for the dismount
	SKIPA			;If bad
	JRST CLNRE9		;Skip following if dismount ok

	SKIPN RSB		;Do we have RSB?
	JRST EXEARB		;No, trouble in river city.  Abort
	CALL STRDMS		;Do the dismount ignoring opr help
	JRST [CALL DISMER	;Still trouble
	      JRST EXEARB]	;Error abort

CLNRE9:	JRST CIPTR9		;Go back to the loop
SUBTTL Process SET CI PORT UNAVAILABLE -- STDUMS - Setup message to resolve dual port

;  Accepts - DSK / disk status block address

STDUMS:	TMCT <The following dual ported disk drive must be resolved
to continue SET PORT CI UNAVAILABLE:%_>

	MOVEI T1,DSKHDR##	;Get the header 
	TMCT <%1A>
	SETZM DSPFLG		;Clear the display flag
	MOVE T1,DSKFLG(DSK)	;Get the status of the disk
	TXNN T1,MS%MNT		;Is there a structure mounted on this disk?
	JRST [CALL WOFRE##	;No, print the unit
	      JRST STDUM1]	
	CALL WOMNT##		;Print the unit

STDUM1:	CALL DSKDSP		;Print any special messages
	TMCT <%_After the dual ported disk has been resolved
Type 'RESPOND <number> option' where 'option' is one of the following:%_
%5CABORT    To cancel Port Unavailable Procedure.
%5CPROCEED  The drive has been single ported to this system.
%5CFORCE    To proceed and ignore the porting of this drive.
%5C           The drive will be set unavailable.>

	RET
SUBTTL Process SET CI PORT UNAVAILABLE -- STREXC - Set structure exclusive with OPR help
COMMENT %

if error to MSTR is not due to CFS then abort port request
otherwise do the same as the dual port code to get operator response.
%

STREXC:	HRRM DSK,RSBDSK(RSB)	;Save DSK
	MOVEI T1,.DSEXC		;Set up exclusive switch request
	CALL OPRSB		;Get RSB
	 JRST [TMCT <%IFailed to acquire RSB for exclusive procedure>
	       JRST EXEARB]	;Error abort
	MOVE T1,PRTRSB		;Get port RSB
	MOVEM T1,RSBSUP(RSB)	;Save it in exclusive RSB

STREX1:	MOVE T1,STRALI(STR)	;Get alias
	TMCT <%IStructure %1S cannot be set exclusive to this system.
After this structure is dismounted from all other systems
Type 'RESPOND <number> option' where 'option' is one of the following:%_
%5CABORT    To cancel Port Unavailable Procedure.
%5CPROCEED  The structure can now be set exclusive to this system.
%5CFORCE    To proceed, ignoring exclusive problem.
%5C           The structure will be dismounted.>
	MOVEI T1,STREXR		;Get return address
	JRST EXRSNR		;Go send message and wait for reply

;  The operator has responded.  Check answer.

;  Reentry point
STREXR: TXO F,PORTF		;Set in port function flag
	MOVEI RSB,-RSBWTB(T2)	;Load RSB ac
	CALL PPTRR		;Parse answer
	 JRST STREX1		;Bad answer, go try again
	SKIPE T1		;Proceed?
	JRST CLNREQ		;No, go clean up request
	CALL SETEXC		;Try to set exclusive
	SKIPA			;Can't, skip good return
	JRST [SETZ T1,		;Set back as proceed
	      JRST CLNREQ]	;Go clean up request
	CAIN T1,MSTX45		;Is another system still using it?
	JRST STREX1		;Yes, operator goofed.  Try again
	ABTREQ(ABRTNR)		;Problem can't handle
	CALL PRQABT		;Clear up RSB
	JRST EXEARB		;Error abort
SUBTTL Process SET CI PORT UNAVAILABLE -- SETEXC - Set structure exclusive if necessary

;  If successful, it will tell the operator.  If not, it returns
;  the error code in T1.

;  Accepts: DSK / Address of DSB

;  Returns: +1 on failure
;	    STR / Address of SSB
;	    T1 / Error code (MSTX45 if due to CFS problem)
;	    +2 if successful

SETEXC:	MOVE T1,DSKFLG(DSK)	;Get status
	TXNN T1,MS%MNT		;Disk part of a mounted structure?
	JRST SETEX9		;No, done with this one

	LOAD STR,DSKSSA,(DSK)	;Get address of SSB
	SKIPN STR		;Is it legit?
	$STOP <Detected mounted disk with bad SSB pointer>
	MOVE T2,STRFL1(STR)	;Get flags
	TXOE T2,STR%EP		;Already exclusive due to PO?
	JRST SETEX9		;Yes, done with this one

	MOVE T1,STRFLG(STR)	;Get structure flags
	TXNE T1,MS%EXC		;Already set exclusive?
	JRST SETEX8		;Yes, go clean up setting bit

	MOVEI T1,STRALI(STR)	;Get address of alias
	MOVE T2,[POINT 7,MSTAL]	;Destination of ascii alias
	CALL SIXSEV		;Translate it
	MOVE T3,[POINT 7,MSTAL]	;Need pointer again
	MOVX T4,MS%EXC		;Exclusive
	MOVE T1,[2,,.MSCSM]	;length 2,,function
	MOVEI T2,T3		;Set up arg block address
	MSTR			;Try to set exclusive
	  ERJMP [MOVEI T1,.FHSLF ;Didn't work, get self
		 GETER		;Get last error
		 HRRZ T1,T2	;Get just error
		 CAIN T1,MSTX45 ;CFS error?
		 RET		;Yes, just return
		 MOVE T2,STRALI(STR) ;Error, get structure name
		 TMCT <%IStructure exclusive failed during procedure%_>
		 TMCT <Problem with structure %2S:%_Error -%1J%_%U>
		 RET]		;Return with error

SETEX8:	SETONE STR%EP,STRFL1(STR) ;Set structure exclusive due to port op.

	MOVE T1,STRALI(STR)	;Get structure name
	TMCT <%IStructure %1S set exclusive due to port unavailable operation>
	MOVEI T3,UNLNOT		;Get header
	CALL BTWTO		;Send message

SETEX9:	RETSKP			;And return good
SUBTTL CIPTUN - Set disk DDB entry to indicate port operation

CIPTUN: MOVE T1,DSKPNT(DSK)	;Get pointer to DDB entry
	CALL DSFGET		;Get the entry
	  CALL STOP		;Should not happen!
	MOVEI T2,1		;Set the bit
	STOR T2,DSF%PO,DSFE+DSFFLG ;Store it
	CALL DSFUDE		;Update entry
	  CALL STOP		;Should not happen
	MOVEI Q1,1		;Say unavailable
	MOVE Q2,DSKCKU(DSK)	;Get CKU
	CALLRET WOMDAV##	;Tell operator
SUBTTL PPTRR - Parse OPR response to query

;	 Parse operator response to querry about type of procedure for
;	 to be used when setting port unavailable.
;  Returns - T1 / -1=Abort 0=Proceed 1=Force

PPTRR:	CALL COMNDI##		;Initialize for COMND jsys
	MOVEI T2,[FLDDB. .CMKEY,,PPTRKS] ;Setup keyword parse
	CALL COMNDX##		;Parse keyword
	 JRST [	MOVEI T1,[ASCIZ/Response must be ABORT, CONT, or FORCE/]
		CALLRET RSPERR##] ;Incorrect response, give error
	HRRZ T2,(T2)		;Get address of keyword processr
	CALLRET (T2)		;Dispatch 

PPTRKS:: PTRKSE,,PTRKSE
	[ASCIZ/ABORT/],,PPTABT
	[ASCIZ/FORCE/],,PPTFOR
	[ASCIZ/PROCEED/],,PPTPRO
PTRKSE==.-PPTRKS-1


;PPTABT - Operator has changed mind.  Abort the request.
;
PPTABT:	SETO T1,		;Set to indicate abortion
	RETSKP
;PPTPRO - Operator wishes to continue, but with caution
;
PPTPRO:	SETZ T1,		;Set to indicate proceed
	RETSKP

;PPTFOR - Operator wishes to continue, but without caution.
;
PPTFOR:	MOVX T1,R%REP		;Get the reply bit
	IORM T1,RSBIFL(RSB)	;Say it is FORCE
	MOVEI T1,1		;Return force
	RETSKP
SUBTTL	Channel Routines

;KSCH - Set up message with list of structures lost if port set unavailable
;
;Accepts: RSB of port operation
;
KSCH:	SETZM ANY		;Mark a variable to indicate none
	SETZM DSPFLG		;Clear the display flag
	HRRZ T2,RSBPRT(RSB)	;Get channel number of request
	TMCT <%ISetting CI Port %2O UNAVAILABLE.%_%_>

	MOVEI T1,.DVDSK		;Get the disk type
	MOVEM T1,DSFE+DSFTYP	;Save it
	SETZ T1,		;Say we have no entries

KSCHLP:	CALL DSFGNX		;Get the disk entry for DDB
	JRST KSCHEN		;All done
	PUSH P,T1		;Save the pointer
	SKIPN DSK,DSFE+DSFPNT	;Do we have a DSK?
	JRST KSCH1		;No get the next
	MOVE T1,DSKFLG(DSK)	;Get status
	TXNN T1,MS%MNT		;Is it mounted
	JRST KSCH1		;No, get next
	HRRZ T2,RSBPRT(RSB)	;Get channel number of request
	LDB T3,[POINT 12,DSKCKU(DSK),11] ;Get channel number
	CAMN T3,T2		;Is it the requested channel
	JRST KSCH2		;Yes, inform operator
	SKIPN CFSB		;Are we a CFS system?
	JRST KSCH1		;No, get next
	TXNN T1,MS%2PT		;Are we dual ported?
	JRST KSCH1		;NO, get next
KSCH2:	SKIPN ANY		;First one?
	JRST [TMCT <The following structure(s) need to be dismounted or removed.%_>
	      SETOM ANY		;We have at least one 
	      MOVEI T2,DSKHDR##	;Get header for mounted drives
	      TMCT <%2A>	;and format the header.
	      JRST .+1]
	TXNE T1,MS%MNT		;Is there a structure mounted on this structure
	JRST [CALL WOMNT##	;Yes, print disk entry
	      JRST KSCH1]
	CALL WOFRE##		;No, print the disk entry
KSCH1:	MOVEI T1,.DVDSK		;Get the type
	MOVEM T1,DSFE+DSFTYP	;Save it
	POP P,T1		;Get the pointer back
	JRST KSCHLP		;Get next dsk

KSCHEN:	SKIPN ANY		;Are there disks affected by ci removal
	JRST	[TMCT <%_There are no structures currently affected %
By setting the port unavailable.%_>
		JRST .+1]
	CALL DSKDSP		;Print any special messages
	TMCT <%_Type 'RESPOND <number> option' where 'option' is one of the following:%_
%5CABORT    To cancel Port Unavailable Procedure.
%5CPROCEED  To follow normal port unavailable procedure verifying
%5C           each structure change.
%5CFORCE    To proceed with no further notification.
%5C           Use this option with extreme caution.>
	
	RET
SUBTTL	DIAG% Routines

;SETPT - Enable/Disable Port
;Accepts: RSB of Port Operation

SETPT:	MOVE T1,[-3,,DIAGBK]	;Size ,, block address
	MOVEI T2,.DGENB		;Get function number
	MOVEM T2,DIAGBK		;Store it in block
	HRRZ T2,RSBPRT(RSB)	;Get channel number
	MOVEM T2,DIAGBK+1	;Store it in block
	SETZM DIAGBK+2		;Assume setting disable
	HLL T2,RSBPRT(RSB)	;Get flags
	TXNN T2,DV.UAV		;Do we really want to disable?
	AOS DIAGBK+2		;No, enable.
	SKIPE TSTF##		;Are we testing?
	JRST SETPFP		;Yes, then don't do diag.
	DIAG
	 ERJMPR [RET]		;Return
	RETSKP

SETPFP:	TMCT <%IDIAG%% would happen here in a non-testing environment.>
	MOVEI T3,[ASCIZ/Function Prohibited In Private Galaxy/]
	CALL BTACKT
	HLL T2,RSBPRT(RSB)	;Get flags
	RETSKP
SUBTTL Common File System Support -- CFSCHK - Check to see whether CFS system

;  Returns: +1 if not been connected in CFS configuration
;	    +2 if another CFS node has been found

CFSCHK:: MOVEI T1,.CFCIN	;Want to get CFS information
	MOVEI T2,.CFCDO+1	;Length of block
	MOVEM T2,CNFBLK+.CFLEN	;Save it
	MOVEI T2,CNFBLK		;Get address of argument block
	CNFIG%			;Get configuration info
	 ERJMP [RET]		;And return no CFS
	MOVE T1,CNFBLK+.CFCDO	;Get the bits
	TXNN T1,CF%CFR		;Have we met another system?
	RET			;No, no CFS
	RETSKP			;Yes, CFS
	END