



		    add_fnp.pl1                     06/04/84  1124.1r w 06/01/84  1443.2       16038



/* ***********************************************************
   *                                                         *
   * Copyright, (C) Honeywell Information Systems Inc., 1984 *
   *                                                         *
   *********************************************************** */
/* add_fnp.pl1 command interface (perhaps interim) to FNP reconfiguration */
/* format: style2 */

add_fnp:
     procedure options (variable);

	declare cu_$arg_count	 entry (fixed bin, fixed bin (35));
	declare cu_$arg_ptr		 entry (fixed bin, ptr, fixed bin (21), fixed bin (35));
	declare com_err_		 entry () options (variable);
	declare parse_fnp_name_	 entry (character (*), fixed binary);
	declare hphcs_$configure_fnp	 entry (fixed bin, fixed bin (35));
	declare ioa_		 entry () options (variable);

	declare ap		 ptr;
	declare al		 fixed bin (21);
	declare argument		 char (al) based (ap);
	declare code		 fixed bin (35);
	declare fnp_no		 fixed bin;
	declare n_args		 fixed bin;
	declare error_table_$bad_channel
				 fixed bin (35) ext static;
	declare ME		 char (32) init ("add_fnp") int static options (constant);


	call cu_$arg_count (n_args, code);
	if code ^= 0
	then do;
		call com_err_ (code, ME);
		return;
	     end;

	if n_args ^= 1
	then do;
		call com_err_ (0, ME, "Usage: add_fnp FNP_TAG");
		return;
	     end;

	call cu_$arg_ptr (1, ap, al, (0));
	call parse_fnp_name_ (argument, fnp_no);
	if fnp_no ^> 0
	then do;
		call com_err_ (error_table_$bad_channel, ME, "Invalid FNP name ^a.", argument);
		return;
	     end;
	call hphcs_$configure_fnp (fnp_no, code);
	if code = 0
	then call ioa_ ("FNP ^a added to configuration.", argument);
	else call com_err_ (code, ME, "Could not add FNP ^a to configuration");
	return;
     end add_fnp;


  



		    delete_fnp.pl1                  07/20/88  1304.9r w 07/19/88  1536.7       52686



/* ***********************************************************
   *                                                         *
   * Copyright, (C) Honeywell Information Systems Inc., 1984 *
   *                                                         *
   *********************************************************** */
/* delete_fnp.pl1 command interface (perhaps interim) to FNP reconfiguration */
/* format: style2 */

delete_fnp:
     procedure options (variable);

	declare cu_$arg_count	 entry (fixed bin, fixed bin (35));
	declare cu_$arg_ptr		 entry (fixed bin, ptr, fixed bin (21), fixed bin (35));
	declare com_err_		 entry () options (variable);
	declare expand_pathname_$add_suffix
				 entry (character (*), character (*), character (*), character (*),
				 fixed binary (35));
	declare get_fnp_name_	 entry (fixed binary) returns (character (32));
	declare multiplexer_mgr_$count_mpx_users
				 entry (character (*), pointer, fixed binary, fixed binary (35));
	declare parse_fnp_name_	 entry (character (*), fixed binary);
	declare pathname_		 entry (character (*), character (*)) returns (character (168));
	declare hphcs_$deconfigure_fnp entry (fixed bin, fixed bin (35));
	declare ioa_		 entry () options (variable);
	declare command_query_$yes_no	 entry () options (variable);
	declare initiate_file_	 entry (character (*), character (*), bit (*), pointer, fixed binary (24),
				 fixed binary (35));
	declare terminate_file_	 entry (pointer, fixed binary (24), bit (*), fixed binary (35));

	declare ap		 ptr;
	declare al		 fixed bin (21);
	declare argument		 char (al) based (ap);
	declare code		 fixed bin (35);
	declare fnp_no		 fixed bin;
	declare argx		 fixed bin;
	declare n_args		 fixed bin;
	declare force		 bit (1) aligned;
	declare test		 bit (1) aligned;
	declare n_users		 fixed bin;
	declare cdt_dir_name	 char (168);
	declare cdt_entryname	 char (32);
	declare query_response	 bit (1) aligned;

	declare error_table_$bad_channel
				 fixed bin (35) ext static;
	declare error_table_$noarg	 fixed bin (35) ext static;
	declare error_table_$too_many_args
				 fixed bin (35) ext static;
	declare error_table_$badopt	 fixed bin (35) ext static;

	declare ME		 char (32) init ("delete_fnp") int static options (constant);
	declare cleanup		 condition;


	call cu_$arg_count (n_args, code);
	if code ^= 0
	then do;
		call com_err_ (code, ME);
		return;
	     end;

	if n_args = 0
	then do;
		call com_err_ (0, ME, "Usage: delete_fnp FNP_TAG {-force} {-test CDT_PATH}");
		return;
	     end;

	force, test = "0"b;
	cdt_dir_name = ">system_control_dir";
	cdt_entryname = "cdt";
	fnp_no = -1;

	do argx = 1 to n_args;
	     call cu_$arg_ptr (argx, ap, al, (0));
	     if index (argument, "-") = 1
	     then do;				/* control argument */
		     if argument = "-force"
		     then force = "1"b;
		     else if argument = "-no_force"
		     then force = "0"b;
		     else if argument = "-test"
		     then do;
			     test = "1"b;
			     if argx = n_args
			     then do;
				     call com_err_ (error_table_$noarg, ME,
					"-test must be followed by a CDT pathname.");
				     return;
				end;
			     argx = argx + 1;
			     call cu_$arg_ptr (argx, ap, al, (0));
			     call expand_pathname_$add_suffix (argument, "cdt", cdt_dir_name, cdt_entryname, code);
			     if code ^= 0
			     then do;
				     call com_err_ (code, ME, "^a.", argument);
				     return;
				end;
			end;
		     else if argument = "-no_test"
		     then do;
			     test = "0"b;
			     cdt_dir_name = ">system_control_dir";
			     cdt_entryname = "cdt";
			end;
		     else do;
			     call com_err_ (error_table_$badopt, ME, "^a.", argument);
			     return;
			end;
		end;
	     else do;
		     if fnp_no > 0			/* already got */
		     then do;
			     call com_err_ (error_table_$too_many_args, ME, "Only one FNP may be specified.");
			     return;
			end;
		     call parse_fnp_name_ (argument, fnp_no);
		     if fnp_no ^> 0
		     then do;
			     call com_err_ (error_table_$bad_channel, ME, "Invalid FNP name ^a.", argument);
			     return;
			end;
		end;				/* FNP Spec */
	end;					/* arg loop */

	cdtp = null ();
	on cleanup
	     begin;
		if cdtp ^= null ()
		then call terminate_file_ (cdtp, (0), TERM_FILE_TERM, (0));
		cdtp = null ();
	     end;

	if ^force
	then do;
		call initiate_file_ (cdt_dir_name, cdt_entryname, R_ACCESS, cdtp, (0), code);
		if code ^= 0
		then do;
			call com_err_ (code, ME,
			     "Could not access ^a to check for users of the FNP. Use -force if you really want to delete it."
			     , pathname_ (cdt_dir_name, cdt_entryname));
			return;
		     end;

		fnpep = addr (cdt.fnp_entry (fnp_no));
		mpxep = addr (fnpe.mpxe);

		if mpxe.state ^= MPX_DOWN & mpxe.state ^= MPX_FREE
						/* might be just running T&D */
		then do;
			call multiplexer_mgr_$count_mpx_users (get_fnp_name_ (fnp_no), cdtp, n_users, code);
			if code ^= 0
			then n_users = 0;		/* something wrong with cdt */
			call command_query_$yes_no (query_response, (0), ME,
			     "Deleting the FNP will crash it and disconnect the users.",
			     "FNP ^a is ^[in an unknown state^;down^;booting^;up^]^[ and has ^d user^[s^]^]. Are you sure that you want to delete it?"
			     , get_fnp_name_ (fnp_no), mpxe.state, n_users > 0, n_users, n_users > 1);
			if ^query_response
			then do;
				call ioa_ ("FNP ^a not deleted.", get_fnp_name_ (fnp_no));
				go to RETURN;
			     end;
		     end;
	     end;
	if test
	then go to RETURN;
	call hphcs_$deconfigure_fnp (fnp_no, code);
	if code = 0
	then call ioa_ ("FNP ^a deleted from configuration.", get_fnp_name_ (fnp_no));
	else call com_err_ (code, ME, "Could not delete FNP ^a from configuration");
RETURN:
	call terminate_file_ (cdtp, (0), TERM_FILE_TERM, (0));

	return;

%include cdt;
%include access_mode_values;
%include terminate_file;
%include author_dcl;
     end delete_fnp;
  



		    obs_reconfigure.pl1             01/17/89  1431.9rew 01/17/89  1342.6      258255



/****^  ***********************************************************
        *                                                         *
        * Copyright, (C) Honeywell Bull Inc., 1988                *
        *                                                         *
        * Copyright, (C) Honeywell Information Systems Inc., 1982 *
        *                                                         *
        * Copyright (c) 1972 by Massachusetts Institute of        *
        * Technology and Honeywell Information Systems, Inc.      *
        *                                                         *
        *********************************************************** */





/****^  HISTORY COMMENTS:
  1) change(88-12-30,Parisek), approve(88-12-30,MCR8040),
     audit(89-01-04,Farley), install(89-01-17,MR12.3-1005):
     Revise the rc_messages array declaration so the second dimension of the
     array represents the actual count of 11 messages.  The eleventh message
     was added for MR12.2.
                                                   END HISTORY COMMENTS */


/* format: style4,delnl,insnl,indattr,ifthen,dclind10 */
reconfigure:
     proc;

/* This program is the user ring interface the supervisor reconfiguration software.
   The following entries (all of which can be invoked as commands) are provided:

   *	addcpu tag
   *	delcpu tag
   *	addmem tag
   *	delmem tag
   *	addmain first_frame n_frames
   *	delmain first_frame n_frames
   *	rc_force_unlock
   *      addchnl chanid
   *	delchnl chanid

   Last modified (date and reason):

   3/9/76 by S. Webber Initial coding
   6/20/83 by S. Krupp for logical channel reconfiguration (addchnl and delchnl).
*/

/* Automatic */

dcl	tp		   ptr;
dcl	arg		   char (16) var aligned;
dcl	arg2		   char (256) var aligned;
dcl	chan_num		   fixed bin (35);
dcl	chanid		   char (8) aligned;
dcl	switches		   (4) bit (36) aligned;
dcl	lace		   bit (1) aligned;
dcl	first		   fixed bin;
dcl	last		   fixed bin;
dcl	n_frames		   fixed bin;
dcl	n_args		   fixed bin;
dcl	tc		   fixed bin;
dcl	code		   fixed bin (35);
dcl	errtag		   fixed bin (3);
dcl	type		   fixed bin;
dcl	tag		   fixed bin (3);
dcl	1 auto_rci	   aligned like rci;
dcl	i		   fixed bin;


/* Static */

dcl	myname		   (7) char (8) aligned static options (constant)
			   init ("addcpu", "delcpu", "addmem", "delmem", "addmain", "delmain", "unlock");
dcl	my_new_name	   (7) char (16) aligned static options (constant)
			   init ("add cpu", "delete cpu", "add mem", "delete mem", "add page", "delete page", "");

dcl	devtype		   (9) char (4) aligned static options (constant)
			   init ("CPU ", "CPU ", "MEM ", "MEM ", "MAIN", "MAIN", "    ", "    ", "    ");

dcl	TAGS		   (0:7) char (1) aligned static options (constant)
			   init ("A", "B", "C", "D", "E", "F", "G", "H");

/* External */

dcl	cv_dec_check_	   entry (char (*), fixed bin (35)) returns (fixed bin (35));
dcl	rc_messages$rc_messages
			   (0:7, 11) char (64) aligned ext;
dcl	error_table_$wrong_no_of_args
			   fixed bin (35) ext;
dcl	error_table_$bad_arg   fixed bin (35) ext;

/* Builtins */

dcl	(addr, index, mod, null, search, substr, unspec)
			   builtin;

/* Based */

dcl	targ		   char (tc) based (tp);

/* Entries */

dcl	hphcs_$add_cpu	   entry (fixed bin (3), (4) bit (36) aligned, fixed bin (35));
dcl	hphcs_$del_cpu	   entry (fixed bin (3), fixed bin (35));
dcl	hphcs_$add_scu	   entry (fixed bin (3), bit (1) aligned, fixed bin (3), fixed bin (35));
dcl	hphcs_$del_scu	   entry (fixed bin (3), bit (1) aligned, fixed bin (35));
dcl	hphcs_$add_main	   entry (fixed bin, fixed bin, fixed bin (35));
dcl	hphcs_$del_main	   entry (fixed bin, fixed bin, fixed bin (35));
dcl	cu_$arg_ptr	   entry (fixed bin, ptr, fixed bin, fixed bin (35));
dcl	cu_$arg_count	   entry (fixed bin, fixed bin (35));
dcl	cv_oct_check_	   entry (char (*), fixed bin (35)) returns (fixed bin);
dcl	com_err_		   entry options (variable);
dcl	hphcs_$reconfig_info   entry (ptr, fixed bin (35));
dcl	hphcs_$rc_force_unlock entry;
dcl	ioa_		   entry options (variable);
dcl	iox_$control	   entry (ptr, char (*), ptr, fixed bin (35));

dcl	iox_$user_output	   ptr ext static;		/*						*/

/*	ADDCPU	ADDCPU	ADDCPU


   This entry assumes and expects a single argument which is the processor tag
   of the processor to be added to the system.

*/

addcpu:
     entry;

	call check_args (1, 8);			/* get argument and reconfig info from ring zero */

	call hphcs_$add_cpu (tag, switches, code);	/* try to add it */
	if code = rcerr_addcpu_bad_switches then do;	/* If config switches in error ... */
	     rswp = addr (switches (2));
	     if dps_rsw_2.fault_base then
		call sw_mess_1 ("Fault Base");
	     if dps_rsw_2.cpu_num ^= 0 then
		call sw_mess_1 ("Processor Number");

	     rswp = addr (switches (4));
	     do i = 0 to 7;
		if i < 4 then
		     pip = addr (addr (switches (1)) -> rsw_1_3.port_info (i));
		else pip = addr (addr (switches (3)) -> rsw_1_3.port_info (i - 4));

		if pi.port_assignment then
		     call sw_mess_2 ("Port Assignment");
		if pi.port_enable then
		     call sw_mess_2 ("Port Enable");
		if pi.interlace_enable | rsw_4.four (i) then
		     call sw_mess_2 ("Interlace");
		if pi.mem_size ^= 0 then
		     call sw_mess_2 ("Size");
		if rsw_4.half (i) then
		     call sw_mess_2 ("Half/Full");
	     end;
	end;

	else if code = rcerr_addcpu_enable then do;
	     unspec (errtag) = switches (1);		/* Get offending SCU tag. */
	     arg2 = TAGS (errtag);
	end;
	if code ^= 0 then
	     call abort (code);			/* wouldn't add, complain */

	call ioa_ ("^a is now running.", arg);
	return;

/**/

/*	DELCPU	DELCPU	DELCPU



   This entry assumes and expects a single argument which is the processor tag of the
   processor to be deleted.

*/

delcpu:
     entry;

	call check_args (2, 8);			/* get argument and reconfig info from ring zero */

	call hphcs_$del_cpu (tag, code);
	if code ^= 0 then
	     call abort (code);			/* couldn't delete it, complain */

	call ioa_ ("Deleted ^a.", arg);
	return;

/**/

/*	ADDMEM	ADDMEM	ADDMEM


   This entry assumes and expects a single argument which is the port number (tag) of the
   system controller to add to the system. All memory attached to the controller is added.
   If parity errors are detected in any frames, those frames are _n_o_t added.


*/

addmem:
     entry;

	call check_args (3, 8);			/* get argument and reconfig info from ring zero */

	call hphcs_$add_scu (tag, lace, errtag, code);
	if code ^= 0 then do;
	     if (code ^= rcerr_addscu_size) & (code ^= rcerr_addscu_manual) then
		arg2 = TAGS (errtag);
	     call abort (code);
	end;

	call print_mem_message ("Added");
	return;



/*	DELMEM	DELMEM	DELMEM


   This entry assumes and expects a single argument which is the port number (tag)
   of the controller to be deleted.

*/

delmem:
     entry;

	call check_args (4, 8);			/* get argument and reconfig info from ring zero */

	call hphcs_$del_scu (tag, lace, code);
	if code ^= 0 then
	     call abort (code);

	call print_mem_message ("Removed");
	return;

/**/

/*	ADDMAIN	ADDMAIN	ADDMAIN


   This entry is called with one or two arguments. The first is the page frame number of
   a block of main memory to be added to the configuration. The second argument is the number
   of contiguous blocks to be added starting with the first. If the second argument is not specified,
   the value 1 is assumed. If the memory is already configured, no complaint is made.

*/

addmain:
     entry;

	call check_args (5, 0);

	call hphcs_$add_main (first, n_frames, code);
	if code ^= 0 then
	     call abort (code);

	call print_main_message ("Added");
	return;




/* 	DELMAIN	DELMAIN	DELMAIN


   This entry is called with one or two arguments. The first is the page frame number of
   a block of main memory to be deleted from the system. The second argument is the number
   of contiguous blocks to be deleted starting with the first. If the second argument is not specified,
   the value 1 is assumed. If the memory is already deleted, no complaint is made.

*/

delmain:
     entry;

	call check_args (6, 0);

	call hphcs_$del_main (first, n_frames, code);
	if code ^= 0 then
	     call abort (code);

	call print_main_message ("Removed");
	return;

/*	FORCE_UNLOCK   	FORCE_UNLOCK   	FORCE_UNLOCK


   This entry is used to forcibly unlock the reconfiguration lock. It is used when
   a reconfiguration request has somehow aborted and left the data bases locked.


*/

force_unlock:
     entry;

	type = 7;
	call hphcs_$reconfig_info (addr (auto_rci), code);
	if code = 0 then
	     call com_err_ (0, myname (type), "Reconfiguration data not locked.");
	else call com_err_ (0, myname (type), "Reconfiguration data locked by ^a", auto_rci.locker_group_id);

	call hphcs_$rc_force_unlock;

	return;

/**/

/*	PRINT_MAIN_MESSAGE	PRINT_MAIN_MESSAGE	PRINT_MAIN_MESSAGE


   This entry is used to print a message about the reconfiguration of the specified
   region of main memory.


*/

print_main_message:
     proc (action);

dcl	action		   char (*);

	if first ^= last then
	     call ioa_ ("^a frames ^o thru ^o.", action, first, last);
	else call ioa_ ("^a frame ^o.", action, first);
	return;

     end;



/*	PRINT_MEM_MESSAGE	PRINT_MEM_MESSAGE	PRINT_MEM_MESSAGE


   This subroutine is used to print a message saying that an SCU and its memory
   have been added or removed from the system. It prints the information for both SCU's if two
   interlaced SCU's were reconfigured.

*/

print_mem_message:
     proc (action);

dcl	action		   char (*);

	if lace then do;
	     tag = tag - mod (tag, 2);
	     call ioa_ ("^a SCU's ^a and ^a (interlaced) and their memory.", action, TAGS (tag), TAGS (tag + 1));
	end;
	else call ioa_ ("^a SCU ^a and its memory.", action, TAGS (tag));
	return;

     end;

/**/

/*	SW_MESS          	SW_MESS          	SW_MESS


   These subroutines are used to interpret configuration switch errors
   when adding a CPU.

*/

sw_mess_1:
     proc (mess);

dcl	mess		   char (*);

	arg2 = arg2 || "
	";
	arg2 = arg2 || mess;

	return;


sw_mess_2:
     entry (mess);

	arg2 = arg2 || "
	";
	arg2 = arg2 || "MEM ";
	arg2 = arg2 || TAGS (i);
	arg2 = arg2 || " ";
	arg2 = arg2 || mess;

	return;

     end;

/**/

/*	CHECK_ARGS	CHECK_ARGS	CHECK_ARGS


   This subroutine is used to pick up the arguments.  It is called with two
   arguments. The first is an integer specifiying which entry to reconfigure was called.
   This may be used later for error message printing. The second argument is the number of values over
   which the command argument may range. For CPU reconfiguration requests it is 4. For controller
   reconfiguration requests it is 8.

*/

check_args:
     proc (t, range);

dcl	t		   fixed bin;
dcl	range		   fixed bin;

	code = 0;
	type = t;
	arg = "";
	arg2 = "";

	call iox_$control (iox_$user_output, "alarm", null (), (0));
						/* try to beep the console */
	call ioa_ ("^a is obsolete.  Use {rcf} ^a instead.", myname (type), my_new_name (type));

	call cu_$arg_count (n_args, code);
	if code ^= 0 then
	     call abort (code);

	if type <= 4 then do;			/* ADDCPU, DELCPU, ADDMEM, and DELMEM */
	     if n_args ^= 1 then
		call abort (error_table_$wrong_no_of_args);
	     call cu_$arg_ptr (1, tp, tc, code);	/* pick up the argument */
	     arg = targ;
	     tag = index (substr ("abcdefgh", 1, range), targ) - 1;
	     if (tag < 0) | (tc ^= 1) then
		call abort (error_table_$bad_arg);
	     arg = devtype (type) || TAGS (tag);
	end;
	else if type <= 6				/* ADDMAIN or DELMAIN */
	then do;
	     if (n_args = 0) | (n_args > 2) then
		call abort (error_table_$wrong_no_of_args);
	     call cu_$arg_ptr (1, tp, tc, code);	/* get port */
	     arg = targ;
	     first = cv_oct_check_ (targ, code);
	     if code ^= 0 then
		call abort (error_table_$bad_arg);
	     if n_args = 2 then do;
		call cu_$arg_ptr (2, tp, tc, code);
		arg = targ;
		n_frames = cv_oct_check_ (targ, code);
		if (code ^= 0) | (n_frames <= 0) then
		     call abort (error_table_$bad_arg);
	     end;
	     else n_frames = 1;

	     arg = devtype (type);
	     last = first + n_frames - 1;
	end;
	else do;
	     if n_args ^= 1 then
		call abort (error_table_$wrong_no_of_args);
	     call cu_$arg_ptr (1, tp, tc, code);
	     if code ^= 0 then
		call abort (code);
	     if ^(tc >= 1 | tc <= 8) then
		call abort (error_table_$bad_arg);
	     if search (targ, "ab") ^= 1 then
		call abort (error_table_$bad_arg);
	     chan_num = cv_dec_check_ (substr (targ, 2), code);
	     if code ^= 0 then
		call abort (code);
	     chanid = targ;
	end;

	return;

     end check_args;

/**/

/* 	ABORT	ABORT	ABORT



   This subroutine is called to report an error from some stage of reconfiguration.
   The input to the routine is

   *	abort_code the parameter

   The abort_code parameter is interpreted differently depending on its value. If it is
   greater than or equal to 7, it indicates a generic problem that can happen with
   all entries. If it is less than 7, it indicates a specific problem with the entry given
   by type.

*/

abort:
     proc (abort_code);

dcl	abort_code	   fixed bin (35);

	if abort_code >= 21 then
	     call com_err_ (abort_code, myname (type), arg);
	else if abort_code >= 11 then
	     call com_err_ (0, myname (type), rc_messages$rc_messages (0, abort_code - 10), arg);
	else call com_err_ (0, myname (type), rc_messages$rc_messages (type, abort_code), arg, arg2);

	goto ERROR;

     end abort;

ERROR:
	return;					/* target of nonlocal goto's */


/**/

%include scs;

/**/

%include rcerr;

%include rci;

/**/

%include rsw;

dcl	pip		   ptr;

dcl	1 pi		   like rsw_1_3.port_info based (pip) unal;

/* BEGIN MESSAGE DOCUMENTATION

   Message:
   Added SCU X and its memory.

   S:	$initializer_io

   T:	$response

   M:	This is the response to a successful addmem X command.

   A:	$ignore


   Message:
   Added SCU's X and Y (interlaced) and their memory.

   S:	$initializer_io

   T:	$response

   M:	This is the response to a successful addmem X command
   when SCU's X and Y have their memories interlaced.

   A:	$ignore


   Message:
   Added frame XXX.

   S:	$initializer_io

   T:	$response

   M:	This is the response to a successful addmain XXX command.

   A:	$ignore


   Message:
   Added frames XXX thru YYY.

   S:	$initializer_io

   T:	$response

   M:	This is the response to a successful addmain XXX N command.

   A:	$ignore


   Message:
   CPU X is now running.

   S:	$initializer_io

   T:	$response

   M:	This is the response to a
   successful addcpu X command.

   A:	$ignore


   Message:
   Deleted CPU X.

   S:	$initializer_io

   T:	$response

   M:	This is the response to a successful delcpu X command.

   A:	$ignore


   Message:
   Removed SCU X and its memory.

   S:	$initializer_io

   T:	$response

   M:	This is the response to a successful delmem X command.

   A:	$ignore


   Message:
   Removed SCU's X and Y (interlaced) and their memory.

   S:	$initializer_io

   T:	$response

   M:	This is the response to a successful delmem X command, when SCU's X and Y are interlaced.

   A:	$ignore


   Message:
   Removed frame XXX.

   S:	$initializer_io

   T:	$response

   M:	This is the response to a successful delmain XXX command.

   A:	$ignore


   Message:
   Removed frames XXX thru YYY.

   S:	$initializer_io

   T:	$response

   M:	This is the response to a successful delmain XXX N command.

   A:	$ignore


   Message:
   addcpu: Associative memories not enabled on CPU X.

   S:	$initializer_io

   T:	$response

   M:	The SDWAM and/or PTWAM on CPU X is not enabled.
   CPU X was not added.

   A:	Set the appropriate associative memory switch on and try addcpu again.


   Message:
   addcpu: CPU X is already online.

   S:	$initializer_io

   T:	$response

   M:	A redundant addcpu X command was issued.
   No action was taken.

   A:	$tryagn


   Message:
   addcpu: CPU X is not configured.

   S:	$initializer_io

   T:	$response

   M:	There is no CPU card for CPU X in the configuration deck.
   The CPU cannot be added.

   A:	If the CPU name was mistyped, enter a corrected command.
   If the configuration deck omitted the CPU card,
   that CPU cannot be added until the system is shut down and the deck corrected.


   Message:
   addcpu: CPU X is not enabled at MEM Y.

   S:	$initializer_io

   T:	$response

   M:	CPU X cannot be added because the PORT ENABLE switch at MEM Y does not enable it.

   A:	Fix the switches and try addcpu again.


   Message:
   addcpu: CPU X is not in Multics mode.

   S:	$initializer_io

   T:	$response

   M:	CPU X cannot be added because its mode switch is wrong.

   A:	Fix the switch and try again.


   Message:
   addcpu: Illegal command or subroutine argument. BLAH

   S:	$initializer_io

   T:	$response

   M:	Invalid input was typed.

   A:	$tryagn


   Message:
   addcpu: Lockup fault trying to start CPU X.

   S:	$initializer_io

   T:	$response

   M:	This happens occasionally. The reason for it is unknown.

   A:	Try addcpu a few more times.


   Message:
   addcpu: No response from CPU X.

   S:	$initializer_io

   T:	$response

   M:	CPU X did not start up when commanded.
   It may be malfunctioning or in STEP.

   A:	Check the switches.
   If any are wrong, correct them and retry addcpu.
   Otherwise, notify Field Engineering.


   Message:
   addcpu: Reconfiguration database is locked.

   S:	$initializer_io

   T:	$response

   M:	Another process is performing reconfiguration currently,
   or a fault during reconfiguration has left the reconfiguration tables locked.

   A:	If it is certain that no other process is reconfiguring,
   and that the fault which interrupted reconfiguration
   has been cured, the reconfigure$force_unlock command may be used to clear the lock
   at the direction of system staff.


   Message:
   addcpu: Startup fault trying to start CPU X.

   S:	$initializer_io

   T:	$response

   M:	This happens sometimes. Nobody knows why.

   A:	Try again a few times.


   Message:
   addcpu: The following switches on CPU X are set incorrectly:
   .br
   Fault Base
   .br
   Processor Number
   .br
   Port Assignment MEM Y
   .br
   Port Enable MEM Y
   .br
   Interlace MEM Y
   .br
   Size MEM Y
   .br
   Half/Full MEM Y

   S:	$initializer_io

   T:	$response

   M:	The listed switches are set incorrectly.

   A:	Correct the switches and try addcpu again.


   Message:
   addcpu: Trouble fault trying to start CPU X.

   S:	$initializer_io

   T:	$response

   M:	This happens sometimes. Nobody knows why.

   A:	Try again a few times.


   Message:
   addcpu: Wrong number of arguments supplied.

   S:	$initializer_io

   T:	$response

   M:	Invalid input was typed.

   A:	$tryagn


   Message:
   addmain: Illegal command or subroutine argument. BLAH

   S:	$initializer_io

   T:	$response

   M:	Invalid input was typed.

   A:	$tryagn


   Message:
   addmain: Reconfiguration database is locked.

   S:	$initializer_io

   T:	$response

   M:	Another process is performing reconfiguration currently,
   or a fault during reconfiguration has left the reconfiguration tables locked.

   A:	If it is certain that no other process is reconfiguring,
   and that the fault which interrupted reconfiguration
   has been cured, the reconfigure$force_unlock command may be used to clear the lock
   at the direction of system staff.


   Message:
   addmain: Request is not within range of a single controller. MAIN XXX

   S:	$initializer_io

   T:	$response

   M:	An addmain command must specify memory completely within the range of a single controller.

   A:	$tryagn


   Message:
   addmain: Wrong number of arguments supplied.

   S:	$initializer_io

   T:	$response

   M:	Invalid input was typed.

   A:	$tryagn


   Message:
   addmem: Illegal command or subroutine argument. BLAH

   S:	$initializer_io

   T:	$response

   M:	Invalid input was typed.

   A:	$tryagn


   Message:
   addmem: MEM Y cannot be accessed by CPU X.

   S:	$initializer_io

   T:	$response

   M:	CPU X is unable to access MEM Y.
   The configuration deck may be incorrect,
   or the CPU and SCU switches may be in the wrong settings.

   A:	Check the switches and make sure that they agree with the configuration deck.
   Then try addmem again.


   Message:
   addmem: MEM Y does not have mask assigned to CPU X.

   S:	$initializer_io

   T:	$response

   M:	The MASK/PORT ASSIGNMENT (4MW SCU)
   or EXECUTE INTERRUPT MASK ASSIGNMENT (6000 SCU)
   switches on SCU Y are incorrect.

   A:	Fix the switches and try addmem again.


   Message:
   addmem: MEM Y has duplicate mask assignments to CPU X.

   S:	$initializer_io

   T:	$response

   M:	The MASK/PORT ASSIGNMENT (4MW SCU)
   or EXECUTE INTERRUPT MASK ASSIGNMENT (6000 SCU)
   switches on SCU Y are incorrect.

   A:	Fix the switches and try addmem again.


   Message:
   addmem: MEM Y has mask Z assigned to non-CPU port.

   S:	$initializer_io

   T:	$response

   M:	The MASK/PORT ASSIGNMENT (4MW SCU)
   or EXECUTE INTERRUPT MASK ASSIGNMENT (6000 SCU)
   switches on SCU Y are incorrect.

   A:	Fix the switches and try addmem again.


   Message:
   addmem: MEM Y is already online.

   S:	$initializer_io

   T:	$response

   M:	An addmem Y command was typed when SCU Y was already online.

   A:	$ignore


   Message:
   addmem: MEM Y is not configured.

   S:	$initializer_io

   T:	$response

   M:	There is no MEM card in the configuration for MEM y.
   The SCU cannot be added.

   A:	If the SCU name was mistyped, enter a corrected command.
   If the configuration deck omitted the MEM card,
   the SCU cannot be added until the system is shut down and the deck corrected.


   Message:
   addmem: MEM Y is not enabled on CPU X.

   S:	$initializer_io

   T:	$response

   M:	The ENABLE switch on the CONFIGURATION panel of CPU X
   does not enable SCU Y.
   The memory cannot be added.

   A:	Fix the switches and try addmem again.


   Message:
   addmem: MEM Y is not in PROGRAM mode.

   S:	$initializer_io

   T:	$response

   M:	The MODE switch on 4MW SCU Y is not in PROGRAM mode.
   The SCU cannot be added.

   A:	Fix the switches and try addmem again.

   A:	$ignore


   Message:
   addmem: Reconfiguration database is locked.

   S:	$initializer_io

   T:	$response

   M:	Another process is performing reconfiguration currently,
   or a fault during reconfiguration has left the reconfiguration tables locked.

   A:	If it is certain that no other process is reconfiguring,
   and that the fault which interrupted reconfiguration
   has been cured, the reconfigure$force_unlock command may be used to clear the lock
   at the direction of system staff.


   Message:
   addmem: Size of MEM Y disagrees with CPU switches.

   S:	$initializer_io

   T:	$response

   M:	The memory size on the configuration card for MEM Y
   disagrees with the size on the CPU switches.

   A:	If the switches are incorrect, fix them and try addmem again.
   If the configuration deck is incorrect,
   the system must be shut down and the deck corrected before the SCU can be added.


   Message:
   addmem: Switches for MEM Y set improperly on CPU X.

   S:	$initializer_io

   T:	$response

   M:	The ADDRESS ASSIGNMENT switches for SCU Y are
   incorrect on CPU X.

   A:	Correct the switches and try addmem again.


   Message:
   addmem: Wrong number of arguments supplied.

   S:	$initializer_io

   T:	$response

   M:	Invalid input was typed.

   A:	$tryagn


   Message:
   delcpu: CPU X is not online.

   S:	$initializer_io

   T:	$response

   M:	A delcpu X command finds that CPU X is already deleted.

   A:	$ignore


   Message:
   delcpu: CPU X is the only CPU.

   S:	$initializer_io

   T:	$response

   M:	A delcpu X command attempted to delete the last CPU.
   No action was taken.

   A:	$ignore


   Message:
   delcpu: Cannot stop CPU X.

   S:	$initializer_io

   T:	$response

   M:	CPU X did not respond to a command to stop within
   the expected time. The CPU may be malfunctioning or in STEP,
   or it may be in a very tight loop.

   A:	Check the CPU panel.
   If the processor appears to be in a loop,
   it may be possible to break it out
   by placing zeros in the processor switches
   and using the EXECUTE button to cause a fault;
   but this action sometimes causes the system to crash,
   depending on where the loop is.


   Message:
   delcpu: Illegal command or subroutine argument. BLAH

   S:	$initializer_io

   T:	$response

   M:	Invalid input was typed.

   A:	$tryagn


   Message:
   delcpu: Reconfiguration database is locked.

   S:	$initializer_io

   T:	$response

   M:	Another process is performing reconfiguration currently,
   or a fault during reconfiguration has left the reconfiguration tables locked.

   A:	If it is certain that no other process is reconfiguring,
   and that the fault which interrupted reconfiguration
   has been cured, the reconfigure$force_unlock command may be used to clear the lock
   at the direction of system staff.


   Message:
   delcpu: Wrong number of arguments supplied.

   S:	$initializer_io

   T:	$response

   M:	Invalid input was typed.

   A:	$tryagn


   Message:
   delmain: Abs wired pages in memory.

   S:	$initializer_io

   T:	$response

   M:	A delmain command attempted to delete a range of pages
   which included some pages which cannot be deleted.
   No action was taken.

   A:	$tryagn


   Message:
   delmain: Illegal command or subroutine argument. BLAH

   S:	$initializer_io

   T:	$response

   M:	Invalid input was typed.

   A:	$tryagn


   Message:
   delmain: Not enough main memory left.

   S:	$initializer_io

   T:	$response

   M:	A delmain command attempted to delete so much memory that the system would be
   unable to function correctly.
   No action was taken.

   A:	$tryagn


   Message:
   delmain: Reconfiguration database is locked.

   S:	$initializer_io

   T:	$response

   M:	Another process is performing reconfiguration currently,
   or a fault during reconfiguration has left the reconfiguration tables locked.

   A:	If it is certain that no other process is reconfiguring,
   and that the fault which interrupted reconfiguration
   has been cured, the reconfigure$force_unlock command may be used to clear the lock
   at the direction of system staff.


   Message:
   delmain: Request is not within range of a single controller. MAIN XXX

   S:	$initializer_io

   T:	$response

   M:	A delmain command must specify a range of pages
   which lies completely within one controller.
   No action was taken.

   A:	$tryagn


   Message:
   delmain: Wrong number of arguments supplied.

   S:	$initializer_io

   T:	$response

   M:	Invalid input was typed.

   A:	$tryagn


   Message:
   delmem: Abs wired pages in MEM Y.

   S:	$initializer_io

   T:	$response

   M:	An attempt was made to delete a memory
   which included some pages which cannot be deleted.
   No action was taken.

   A:	The memory cannot be deleted.


   Message:
   delmem: Illegal command or subroutine argument. BLAH

   S:	$initializer_io

   T:	$response

   M:	Invalid input was typed.

   A:	$tryagn


   Message:
   delmem: MEM Y is not online.

   S:	$initializer_io

   T:	$response

   M:	A delmem Y command was typed but no such memory is in use.

   A:	$ignore


   Message:
   delmem: Not enough main memory to remove MEM Y.

   S:	$initializer_io

   T:	$response

   M:	The system would be unable to function
   correctly if SCU Y and its memory were deleted.
   No action was taken.

   A:	Try something else.


   Message:
   delmem: Reconfiguration database is locked.

   S:	$initializer_io

   T:	$response

   M:	Another process is performing reconfiguration currently,
   or a fault during reconfiguration has left the reconfiguration tables locked.

   A:	If it is certain that no other process is reconfiguring,
   and that the fault which interrupted reconfiguration
   has been cured, the reconfigure$force_unlock command may be used to clear the lock
   at the direction of system staff.


   Message:
   delmem: Wrong number of arguments supplied.

   S:	$initializer_io

   T:	$response

   M:	Invalid input was typed.

   A:	$tryagn


   Message:
   unlock: Reconfiguration data locked by PERSON.PROJ.T

   S:	$initializer_io

   T:	$response

   M:	This message is typed by reconfigure$force_unlock if the reconfiguration data base was locked.

   A:	$ignore


   Message:
   unlock: Reconfiguration data not locked.

   S:	$initializer_io

   T:	$response

   M:	This message is typed by reconfigure$force_unlock if the reconfiguration data base was not locked.

   A:	$ignore


   END MESSAGE DOCUMENTATION */

     end reconfigure;
 



		    rc_messages.cds                 10/14/88  1319.0rew 10/14/88  1308.5       44892



/* ***********************************************************
   *                                                         *
   * Copyright, (C) Honeywell Bull Inc., 1988                *
   *                                                         *
   * Copyright, (C) Honeywell Information Systems Inc., 1982 *
   *                                                         *
   * Copyright (c) 1972 by Massachusetts Institute of        *
   * Technology and Honeywell Information Systems, Inc.      *
   *                                                         *
   *********************************************************** */





/* HISTORY COMMENTS:
  1) change(88-07-27,Farley), approve(88-10-05,MCR7968),
     audit(88-10-10,Beattie), install(88-10-14,MR12.2-1166):
     Added message for new rcerr_addscu_memoverlap error.
                                                   END HISTORY COMMENTS */


rc_messages: proc;

/* This data base includes the messages that are reported during dynamic reconfiguration
   of system controllers and processors.

   The data base consists of a two dimensional array of character strings. The first
   dimension indicates the type of reconfiguration command as follows:

   *	0	general
   *	1	add cpu
   *	2	dl cpu
   *	3	add mem
   *	4	dl mem
   *	5	add page
   *	6	dl page

   The second dimension is controlled by the particular reconfiguration request.

   Modified March 1976 by Steve Webber --- Initial coding
   Modified Feb 1979 by BSG for 8-cpu port expander
   Modified Dec 1979 by Mike Grady for new add scu message
   Modified August 1984 by Chris Jones for new reconfiguration commands
*/

/* Automatic */

dcl 1 cdsa aligned like cds_args;
dcl  code fixed bin (35);
dcl 1 rc_messages_array aligned,
    2 rc_messages (0:7, 11) char (64) aligned;
dcl (addr, null, size, string) builtin;

/* Entries */

dcl  create_data_segment_ entry (ptr, fixed bin (35));

/* Now begins the initialization */

	string (rc_messages_array) = "";

	rc_messages (0, rcerr_locked - 11) = "Reconfiguration database is locked.";
	rc_messages (0, rcerr_online - 11) = "^a is already online.";
	rc_messages (0, rcerr_no_config - 11) = "^a is not configured.";
	rc_messages (0, rcerr_not_online - 11) = "^a is not online.";
	rc_messages (0, rcerr_range - 11) = "Request is not within range of a single controller.";
	rc_messages (0, rcerr_sprq_failed - 11) = "Could not set CPU required.";

	rc_messages (1, rcerr_addcpu_no_response) = "No response from ^a.";
	rc_messages (1, rcerr_addcpu_bad_switches) = "The following switches on ^a are set incorrectly: ^a";
	rc_messages (1, rcerr_addcpu_trouble) = "Trouble fault trying to start ^a.";
	rc_messages (1, rcerr_addcpu_startup) = "Startup fault trying to start ^a.";
	rc_messages (1, rcerr_addcpu_lockup) = "Lockup fault trying to start ^a.";
	rc_messages (1, rcerr_addcpu_gcos) = "^a is not in Multics mode.";
	rc_messages (1, rcerr_addcpu_amoff) = "Associative memories not enabled on ^a.";
	rc_messages (1, rcerr_addcpu_enable) = "^a is not enabled at MEM ^a.";

	rc_messages (2, rcerr_delcpu_no_stop) = "Cannot stop ^a.";
	rc_messages (2, rcerr_delcpu_last) = "^a is the only CPU.";
	rc_messages (2, rcerr_delcpu_no_good_blcpu) = "No acceptable bootload CPU would be left.";

	rc_messages (3, rcerr_addscu_size) = "Size of ^a disagrees with CPU switches.";
	rc_messages (3, rcerr_addscu_dup_mask) = "^a has duplicate mask assignments to CPU ^a.";
	rc_messages (3, rcerr_addscu_no_mask) = "^a does not have mask assigned to CPU ^a.";
	rc_messages (3, rcerr_addscu_bad_mask) = "^a has mask ^a assigned to non-CPU port.";
	rc_messages (3, rcerr_addscu_fault) = "^a cannot be accessed by CPU ^a.";
	rc_messages (3, rcerr_addscu_switches) = "Switches for ^a set improperly on CPU ^a.";
	rc_messages (3, rcerr_addscu_enable) = "^a is not enabled on CPU ^a.";
	rc_messages (3, rcerr_addscu_manual) = "^a is not in PROGRAM mode.";
	rc_messages (3, rcerr_addscu_oldexpand) = "^a is a 6000 SCU which may not have a port expander.";
	rc_messages (3, rcerr_addscu_bigconfig) = "^a has less memory than config card indicates.";
	rc_messages (3, rcerr_addscu_memoverlap) = "^a has a possible memory address overlap problem.";

	rc_messages (4, rcerr_delmain_nomem) = "Not enough main memory to remove ^a.";
	rc_messages (4, rcerr_delmain_abs_wired) = "Abs wired pages in ^a.";

	rc_messages (6, rcerr_delmain_nomem) = "Not enough main memory left.";
	rc_messages (6, rcerr_delmain_abs_wired) = "Abs wired pages in memory.";


/* Now set up call to create data base */

	cdsa.sections (1).p = addr (rc_messages_array);
	cdsa.sections (1).len = size (rc_messages_array);
	cdsa.sections (1).struct_name = "rc_messages_array";

	cdsa.seg_name = "rc_messages";
	cdsa.num_exclude_names = 0;
	cdsa.exclude_array_ptr = null ();

	string (cdsa.switches) = "0"b;
	cdsa.switches.have_text = "1"b;

	call create_data_segment_ (addr (cdsa), code);
%page;
% include rcerr;
%page;
% include cds_args;

     end rc_messages;




		    reconfigure.pl1                 01/17/89  1431.9rew 01/17/89  1342.8      344790



/****^  ***********************************************************
        *                                                         *
        * Copyright, (C) Honeywell Bull Inc., 1987                *
        *                                                         *
        * Copyright, (C) Honeywell Information Systems Inc., 1984 *
        *                                                         *
        *********************************************************** */

/****^  HISTORY COMMENTS:
  1) change(85-09-09,Farley), approve(85-09-09,MCR6979),
     audit(85-12-02,CLJones), install(86-03-21,MR12.0-1033):
     Fixed to continue
     adding devices if one cannot be added, if the add_all_attachment was
     given.
  2) change(87-06-12,Lippard), approve(87-06-29,MCR7729),
     audit(87-07-08,Farley), install(86-08-06,MR12.1-1064):
     Changed to allow -delete_all_attachments for IOMs when some channels
     have already been deleted.
  3) change(87-10-22,Parisek), approve(87-10-29,MCR7790),
     audit(88-04-28,GDixon), install(88-05-04,MR12.2-1045):
     Replace a call to com_err_ with a call to ioa_ for reporting an error
     resulting from attempting to delete a device which is already in the
     deleted state.
  4) change(88-12-07,Parisek), approve(88-12-30,MCR8040),
     audit(89-01-04,Farley), install(89-01-17,MR12.3-1005):
     Revise the rc_messages array declaration so the second dimension of the
     array represents the actual count of 11 messages.  The eleventh message
     was added for MR12.2.
                                                   END HISTORY COMMENTS */
/* User-ring and operator interface to reconfiguration software. */
/* Written May 1984 by Chris Jones. */
/* Bugfixes from exposure, July 1984, Chris Jones */
/* Modified to add -force, August 1984, Chris Jones */
/* Modified to avoid duplicate messages on operators' console, add sc_reconfigure_request entrypoint,
   November 1984, Chris Jones */
/* Modified to use ioa_ on non-error messages, parse fnp names correctly, January 1985, Chris Jones */
/* Modified to correctly handle adding and removing disks with "*_all_attachments", May 1985, Chris Jones */
/* Modified to continue adding devices if one cannot be added, if the add_all_attachment was given. Sept 1985, Paul Farley */

/* format: style4,delnl,insnl,indattr,ifthen,dclind10 */

reconfigure:
rcf:
     proc options (variable);

dcl	action		   fixed bin;		/* says what kind of thing we're doing */
dcl	add_all_sw	   bit (1) aligned;		/* set if -add_all_attachments given */
dcl	add_del_sw	   bit (1) aligned;		/* indicates add or delete operation */
dcl	arg_count		   fixed bin;		/* number of arguments we were invoked with */
dcl	arg_idx		   fixed bin;		/* current argument number */
dcl	arg_state		   fixed bin;		/* denotes which of operation, type, or name is next */
dcl	backing_out	   bit (1) aligned;		/* set if we're backing out what we've done */
dcl	backout_list_ptr	   ptr;			/* pointer to list of things to undo if we have problems */
dcl	brief_sw		   bit (1) aligned;		/* set if -brief given */
dcl	cdtp		   ptr;
dcl	channel_idx	   fixed bin;		/* index into io_config_data.channel_table */
dcl	code		   fixed bin (35);		/* system status code */
dcl	control_arg	   bit (1) aligned;		/* set if current arg is a control arg */
dcl	deadline		   fixed bin (71);		/* when Godot has to go it alone */
dcl	delete_all_sw	   bit (1) aligned;		/* set if -delete_all_attachments given */
dcl	device_idx	   fixed bin;		/* index into device_table */
dcl	error_tag		   fixed bin (3);		/* tag of SCU where problem occurred */
dcl	first_frame	   fixed bin;		/* first memory frame to play with */
dcl	force_sw		   bit (1) aligned;		/* set if -force used */
dcl	i		   fixed bin;		/* random index */
dcl	iom_idx		   fixed bin;		/* index into iom_table */
dcl	interlace		   bit (1) aligned;		/* set if an SCU is externally interlaced */
dcl	mpc_idx		   fixed bin;		/* index into controller_table */
dcl	n_frames		   fixed bin;		/* number of frames to play with */
dcl	name		   char (32);		/* name of the thing we're fiddling with */
dcl	reason		   char (256) varying;	/* used for error messages */
dcl	sci_ptr		   ptr;			/* info pointer for ssu_ */
dcl       standalone_invocation  bit (1) aligned;		/* On if called as command rather than an ssu request */
dcl	switches		   (4) bit (36) aligned;	/* results from rsw's on a CPU */
dcl	tag		   fixed bin (3);		/* CPU, IOM, or SCU identifier */
dcl	type_idx		   fixed bin;		/* denotes what kind of thing we're playing with */

dcl	arg		   char (argl) based (argp);
dcl	argl		   fixed bin (21);
dcl	argp		   ptr;

dcl	1 pi		   like rsw_1_3.port_info based (pip) unal;
						/* port info for one port (from rsw) */
dcl	pip		   ptr;

dcl	area		   area based (area_ptr);
dcl	area_ptr		   ptr;

dcl	1 backout_item	   aligned based (item_ptr),	/* what we have to undo when we cleanup */
	  2 idx		   fixed bin,		/* how we reference it */
	  2 type		   char (8),		/* "device", "channel", or "iom" */
	  2 next_item	   ptr;			/* forward pointer */
dcl	item_ptr		   ptr;
dcl	ADD		   bit (1) aligned static options (constant) init ("1"b);
dcl	DELETE		   bit (1) aligned static options (constant) init ("0"b);

dcl	TYPES		   (15) char (16) static options (constant)
			   init ("channel", "chan", "chnl", "cpu", "device", "dv", "prph", "iom", "link_adapter",
			   "la", "mpc", "page", "pages", "mem", "scu");

dcl	ACTIONS		   (15) fixed bin static options (constant)
			   init (5, 5, 5, 1, 4, 4, 4, 8, 6, 6, 7, 3, 3, 2, 2);
dcl	ME		   char (16) static options (constant) init ("reconfigure");
dcl	RCF_V1		   char (4) static options (constant) init ("1.00");
dcl	RANGE_SEPARATOR	   char (1) static options (constant) init (":");
dcl	REASON_SEPARATOR	   char (2) static options (constant) init ("
	");

dcl	TAGS_STRING	   char (8) static options (constant) init ("abcdefgh");
dcl	TAGS_STRING_UPPER_CASE char (8) static options (constant) init ("ABCDEFGH");
dcl	TAGS		   (0:7) char (1) unal defined TAGS_STRING;

dcl	TEN_SECONDS	   fixed bin (71) static options (constant) init (10000000);

dcl	error_table_$action_not_performed
			   fixed bin (35) ext static;
dcl	error_table_$bad_arg   fixed bin (35) ext static;
dcl	error_table_$badopt	   fixed bin (35) ext static;
dcl	error_table_$chnl_already_deleted
			   fixed bin (35) ext static;
dcl	error_table_$inconsistent
			   fixed bin (35) ext static;
dcl	error_table_$io_not_configured
			   fixed bin (35) ext static;
dcl	error_table_$io_not_defined
			   fixed bin (35) ext static;
dcl	error_table_$noarg	   fixed bin (35) ext static;
dcl	error_table_$not_base_channel
			   fixed bin (35) ext static;
dcl	error_table_$too_many_args
			   fixed bin (35) ext static;
dcl	error_table_$unimplemented_version
			   fixed bin (35) ext static;

dcl	rc_messages$rc_messages
			   (0:7, 11) char (64) aligned ext;

dcl	com_err_		   entry () options (variable);
dcl	cu_$arg_list_ptr	   entry (ptr);
dcl	cv_integer_string_check_
			   entry (char (*), fixed bin, fixed bin (35)) returns (fixed bin (35));
dcl	hphcs_$add_channel	   entry (char (8) aligned, fixed bin (35));
dcl	hphcs_$add_cpu	   entry (fixed bin (3), (4) bit (36) aligned, fixed bin (35));
dcl	hphcs_$add_iom	   entry (fixed bin (3), fixed bin (35));
dcl	hphcs_$add_main	   entry (fixed bin, fixed bin, fixed bin (35));
dcl	hphcs_$add_scu	   entry (fixed bin (3), bit (1) aligned, fixed bin (3), fixed bin (35));
dcl	hphcs_$del_cpu	   entry (fixed bin (3), fixed bin (35));
dcl	hphcs_$del_scu	   entry (fixed bin (3), bit (1) aligned, fixed bin (35));
dcl	hphcs_$del_main	   entry (fixed bin, fixed bin, fixed bin (35));
dcl	hphcs_$delete_channel  entry (char (8) aligned, fixed bin (35));
dcl	hphcs_$delete_iom	   entry (fixed bin (3), fixed bin (35));
dcl	ioa_		   entry () options (variable);
dcl	ioa_$general_rs	   entry (ptr, fixed bin, fixed bin, char (*), fixed bin (21), bit (1) aligned,
			   bit (1) aligned);
dcl	rcp_sys_$add_device	   entry (char (*), fixed bin (35));
dcl	rcp_sys_$delete_device entry (char (*), fixed bin (35));
dcl	ssu_$abort_line	   entry () options (variable);
dcl	ssu_$arg_count	   entry (ptr, fixed bin);
dcl	ssu_$arg_ptr	   entry (ptr, fixed bin, ptr, fixed bin (21));
dcl	ssu_$destroy_invocation
			   entry (ptr);
dcl	ssu_$get_area	   entry (ptr, ptr, char (*), ptr);
dcl	ssu_$print_message	   entry () options (variable);
dcl	ssu_$release_area	   entry (ptr, ptr);
dcl	ssu_$standalone_invocation
			   entry (ptr, char (*), char (*), ptr, entry, fixed bin (35));
dcl       terminate_file_        entry (ptr, fixed bin (24), bit (*), fixed bin (35));

dcl	(addr, after, bin, clock, hbound, index, lbound, mod, null, ptr, rtrim, substr, translate)
			   builtin;

dcl	cleanup		   condition;

          standalone_invocation = "1"b;
          sci_ptr, sc_subsystem_info_ptr, cdtp, backout_list_ptr,
	     area_ptr = null ();
	on cleanup begin;
	     call backout_work_so_far;
	     call clean_up;
	end;
	call ssu_$standalone_invocation (sci_ptr, ME, RCF_V1, null (), abort_entry, code);
	if code ^= 0 then do;
	     call com_err_ (code, ME, "Could not create ssu_ invocation.");
	     return;
	end;
	goto RECONFIGURE_COMMON;

sc_reconfigure_request:
     entry (p_sci_ptr, p_ssu_info_ptr);

dcl	p_sci_ptr		   ptr;			/* invocation structure pointer */
dcl	p_ssu_info_ptr	   ptr;			/* pointer to subsystem info */

          standalone_invocation = "0"b;
          cdtp = null ();
	backout_list_ptr, area_ptr = null ();
	sci_ptr = p_sci_ptr;
	sc_subsystem_info_ptr = p_ssu_info_ptr;
	on cleanup begin;
	     call backout_work_so_far;
	     call clean_up;
	end;

RECONFIGURE_COMMON:
	backing_out = "0"b;
	call ssu_$arg_count (sci_ptr, arg_count);
	if arg_count = 0 then
	     call quit_with_usage (0);
	else if arg_count < 3 then
	     call quit_with_usage (error_table_$noarg);
	call ssu_$get_area (sci_ptr, null (), "undo list", area_ptr);

	add_all_sw, delete_all_sw = "0"b;
	brief_sw = "0"b;
	force_sw = "0"b;
	arg_state = 0;				/* have seen no non-control arguments */
	reason = "";
	do arg_idx = 1 to arg_count;
	     call ssu_$arg_ptr (sci_ptr, arg_idx, argp, argl);
	     if argl > 0 then
		if substr (arg, 1, 1) = "-" then
		     control_arg = "1"b;
		else control_arg = "0"b;
	     else control_arg = "0"b;

	     if control_arg then do;
		if arg = "-add_all_attachments" then
		     add_all_sw = "1"b;
		else if arg = "-brief" | arg = "-bf" then
		     brief_sw = "1"b;
		else if arg = "-delete_all_attachments" then
		     delete_all_sw = "1"b;
		else if arg = "-long" | arg = "-lg" then
		     brief_sw = "0"b;
		else if arg = "-force" | arg = "-fc" then
		     force_sw = "1"b;
		else if arg = "-no_force" | arg = "-nfc" then
		     force_sw = "0"b;
		else call quit (error_table_$badopt, arg);
	     end;
	     else do;				/* non-control arg */
		arg_state = arg_state + 1;		/* one more non-control argument */

		if arg_state = 1 then do;
		     if arg = "add" then
			add_del_sw = ADD;
		     else if arg = "delete" | arg = "dl" then
			add_del_sw = DELETE;
		     else call quit (error_table_$bad_arg, arg);
		end;
		else if arg_state = 2 then do;
		     do type_idx = lbound (TYPES, 1) to hbound (TYPES, 1) while (TYPES (type_idx) ^= arg);
		     end;
		     if type_idx > hbound (TYPES, 1) then
			call quit (error_table_$bad_arg, arg);
		     action = ACTIONS (type_idx);
		end;
		else if arg_state = 3 then do;
		     name = arg;			/* we'll accept anything for the name at this point */
		end;
		else call quit (error_table_$too_many_args);
	     end;
	end;

	if arg_state ^= 3 then			/* don't have all the pieces */
	     call quit_with_usage (error_table_$noarg);
	if (add_all_sw & add_del_sw = DELETE) | (delete_all_sw & add_del_sw = ADD) then
	     call quit (error_table_$inconsistent);

/**** At this point, we know what we want to do.   Now, go do it. ****/

	goto ACTION_LABEL (action);			/* n-way branch on type of thing to reconfigure */

ACTION_LABEL (0):
	call quit (error_table_$bad_arg, "The request is not yet implemented.");

/**** CPUs ****/

ACTION_LABEL (1):					/* CPU */
	tag = get_tag_from_name (name) - 1;
	name = "CPU " || rtrim (name);		/* for better error messages */
	if add_del_sw = ADD then do;			/* add case */
	     call hphcs_$add_cpu (tag, switches, code);
	     if code = rcerr_addcpu_bad_switches then do; /* If config switches in error ... */
		rswp = addr (switches (2));
		if dps_rsw_2.fault_base then
		     call generate_switch_message ("Fault Base");
		if dps_rsw_2.cpu_num ^= 0 then
		     call generate_switch_message ("Processor Number");

		rswp = addr (switches (4));
		do i = 0 to 7;
		     if i < 4 then
			pip = addr (addr (switches (1)) -> rsw_1_3.port_info (i));
		     else pip = addr (addr (switches (3)) -> rsw_1_3.port_info (i - 4));

		     if pi.port_assignment then
			call generate_switch_memory_message ("Port Assignment");
		     if pi.port_enable then
			call generate_switch_memory_message ("Port Enable");
		     if pi.interlace_enable | rsw_4.four (i) then
			call generate_switch_memory_message ("Interlace");
		     if pi.mem_size ^= 0 then
			call generate_switch_memory_message ("Size");
		     if rsw_4.half (i) then
			call generate_switch_memory_message ("Half/Full");
		end;
	     end;

	     else if code = rcerr_addcpu_enable then do;
		reason = TAGS (bin (switches (1)));	/* Get offending SCU tag. */
	     end;
	     if code ^= 0 then
		call quit_if_rc_error (code);

	     if message_is_called_for () then
		call ioa_ ("^a is now running.", name);
	end;
	else do;					/* delete a CPU */
	     call hphcs_$del_cpu (tag, code);
	     if code ^= 0 then
		call quit_if_rc_error (code);
	     if message_is_called_for () then
		call ioa_ ("Deleted ^a.", name);
	end;
	goto DONE;

generate_switch_message:
     proc (aspect);

dcl	aspect		   char (*) parameter;

	reason = reason || REASON_SEPARATOR;
	reason = reason || aspect;
	return;

generate_switch_memory_message:
     entry (aspect);

	reason = reason || REASON_SEPARATOR;
	reason = reason || "MEM ";
	reason = reason || TAGS (i);
	reason = reason || " ";
	reason = reason || aspect;

     end generate_switch_message;

ACTION_LABEL (2):					/* SCU */
	tag = get_tag_from_name (name) - 1;
	name = "MEM " || rtrim (name);		/* for better error messages */
	if add_del_sw = ADD then do;			/* adding an SCU */
	     call hphcs_$add_scu (tag, interlace, error_tag, code);
	     if code ^= rcerr_addscu_size & code ^= rcerr_addscu_manual & code ^= 0 & code ^= rcerr_addscu_bigconfig
		then
		reason = TAGS (error_tag);
	     if code ^= 0 then
		call quit_if_rc_error (code);
	     call print_scu_message;
	end;
	else do;					/* deleting an SCU */
	     call hphcs_$del_scu (tag, interlace, code);
	     if code ^= 0 then
		call quit_if_rc_error (code);
	     call print_scu_message;
	end;
	goto DONE;

print_scu_message:
     proc;

	if message_is_called_for () then
	     call ioa_ ("^[Added^;Removed^] SCU^[s ^s^a and ^a (interlaced)^; ^a^2s^] and ^[their^;its^] memory.",
		add_del_sw = ADD, interlace, TAGS (tag), TAGS (tag - mod (tag, 2)), TAGS (tag + 1 - mod (tag, 2)),
		interlace);

     end print_scu_message;

ACTION_LABEL (3):					/* pages */
	i = index (name, RANGE_SEPARATOR);
	if i = 0 then do;				/* only one page */
	     first_frame = cv_integer_string_check_ (name, 8, code);
	     if code ^= 0 then
		call quit (code, name);
	     n_frames = 1;
	end;
	else do;
	     first_frame = cv_integer_string_check_ (substr (name, 1, i - 1), 8, code);
	     if code ^= 0 then
		call quit (code, substr (name, 1, i - 1));
	     n_frames = cv_integer_string_check_ (substr (name, i + 1), 8, code);
	     if code ^= 0 then
		call quit (code, substr (name, i + 1));
	     n_frames = n_frames - first_frame + 1;
	end;
	if add_del_sw = ADD then
	     call hphcs_$add_main (first_frame, n_frames, code);
	else call hphcs_$del_main (first_frame, n_frames, code);
	if code ^= 0 then
	     call quit_if_rc_error (code);
	if message_is_called_for () then
	     call ioa_ ("^[Added^;Removed^] frame^[s ^o thru ^o^; ^o^s^].", add_del_sw = ADD, n_frames ^= 1,
		first_frame, first_frame + n_frames - 1);
	goto DONE;

ACTION_LABEL (4):					/* device */
	call setup_io_config_ptrs;
	do device_idx = lbound (device_table.device_entry, 1) to hbound (device_table.device_entry, 1)
	     while (device_table.device_entry (device_idx).name ^= name);
	end;
	if device_idx > hbound (device_table.device_entry, 1) then do;
	     code = error_table_$io_not_defined;
	     return;
	end;
	if add_del_sw = ADD then
	     call add_device (device_idx, code);
	else call delete_device (device_idx, code);
	if code ^= 0 then
	     call quit (code, "Device ^a.", name);
	if message_is_called_for () then
	     call ioa_ ("^[Added^;Removed^] device ^a.", add_del_sw = ADD, name);
	goto DONE;

add_device:
     proc (idx, code);

dcl	idx		   fixed bin parameter;
dcl	code		   fixed bin (35) parameter;

dcl	desired_configured_setting
			   bit (1) aligned;

	call rcp_sys_$add_device (device_table.device_entry (idx).name, code);
	desired_configured_setting = "1"b;
add_del_device_common:
	if code ^= 0 then
	     return;
	deadline = clock () + TEN_SECONDS;
	do while (clock () < deadline & device_table.device_entry (idx).configured ^= desired_configured_setting);
	end;
	if device_table.device_entry (idx).configured = desired_configured_setting then do;
	     code = 0;
	     call add_to_backout_list (idx, "device");
	end;
	else code = error_table_$action_not_performed;
/**** RCP should do this work ****/
	if device_type (idx) = "fnp" & desired_configured_setting then
	     call add_fnp (idx, code);
	return;

delete_device:
     entry (idx, code);

	if device_type (idx) = "fnp" then do;
	     call delete_fnp (idx, code);
	     if code ^= 0 then
		return;
	end;
	call rcp_sys_$delete_device (device_table.device_entry (idx).name, code);
	desired_configured_setting = "0"b;
	goto add_del_device_common;

     end add_device;

/**** This work should more properly be done in RCP when it gets an FNP device type. ****/

add_fnp:
     proc (idx, code);

dcl	idx		   fixed bin parameter;
dcl	code		   fixed bin (35) parameter;

dcl	n_users		   fixed bin;

dcl	hphcs_$configure_fnp   entry (fixed bin, fixed bin (35));
dcl	hphcs_$deconfigure_fnp entry (fixed bin, fixed bin (35));
dcl	initiate_file_	   entry (char (*), char (*), bit (*), ptr, fixed bin (24), fixed bin (35));
dcl	multiplexer_mgr_$count_mpx_users
			   entry (char (*), ptr, fixed bin, fixed bin (35));
dcl	parse_fnp_name_	   entry (char (*)) returns (fixed bin);

dcl	error_table_$io_configured
			   fixed bin (35) ext static;
dcl	error_table_$io_not_available
			   fixed bin (35) ext static;
dcl	error_table_$io_not_configured
			   fixed bin (35) ext static;

	call hphcs_$configure_fnp (parse_fnp_name_ (after (device_table.device_entry (idx).name, "fnp")), code);
	if code = error_table_$io_configured then
	     code = 0;
	return;

delete_fnp:
     entry (idx, code);

	if ^force_sw then do;
	     call initiate_file_ (">sc1", "cdt", R_ACCESS, cdtp, (0), code);
	     if code ^= 0 then
		return;
	     call multiplexer_mgr_$count_mpx_users (substr (device_table.device_entry (idx).name, 4), cdtp, n_users,
		code);
	     call terminate_file_ (cdtp, (0), TERM_FILE_TERM, (0));
	     cdtp = null ();
	     if (code = 0) & (n_users > 0) then do;
		code = error_table_$io_not_available;
		return;
	     end;
	end;
	call hphcs_$deconfigure_fnp (parse_fnp_name_ (after (device_table.device_entry (idx).name, "fnp")), code);
	if code = error_table_$io_not_configured then
	     code = 0;
	return;

%include access_mode_values;

     end add_fnp;

ACTION_LABEL (5):					/* channels */
	call setup_io_config_ptrs;
	call canonicalize_channel_name (name);
	do channel_idx = lbound (channel_table.channel_entry, 1) to hbound (channel_table.channel_entry, 1)
	     while (name ^= channel_table.channel_entry (channel_idx).name);
	end;
	if channel_idx > hbound (channel_table.channel_entry, 1) then
	     call quit (error_table_$io_not_defined, "Channel ^a.", name);
	if add_del_sw = ADD then do;
	     call add_channel (channel_idx, code);
	     if code ^= 0 then
		call quit (code, "Channel ^a.", name);
	end;
	else do;
	     if delete_all_sw then do;
		call delete_devices (channel_idx, code);
		if code ^= 0 then
		     call quit (code, "Channel ^a.", name);
	     end;
	     call delete_channel (channel_idx, code);
	     if code ^= 0 then
		call quit (code, "Channel ^a.", name);
	end;
	if message_is_called_for () then
	     call ioa_ ("^[Added^;Removed^] logical channel ^a.", add_del_sw = ADD,
		channel_table.channel_entry (idx).name);
	goto DONE;

add_channel:
     proc (idx, code);

dcl	idx		   fixed bin parameter;
dcl	code		   fixed bin (35) parameter;

dcl	add_entry		   bit (1) aligned;

	add_entry = "1"b;
	call hphcs_$add_channel (channel_table.channel_entry (idx).name, code);
	goto add_delete_channel_common;

delete_channel:
     entry (idx, code);

	add_entry = "0"b;
	if delete_all_sw then do;
	     call delete_devices (idx, code);
	     if code ^= 0 then
		return;
	end;
	call hphcs_$delete_channel (channel_table.channel_entry (idx).name, code);
add_delete_channel_common:
	if code = 0 then do;
	     call add_to_backout_list (idx, "channel");
	     if add_all_sw then
		call add_devices (idx, code);
	end;
	return;

     end add_channel;

/**** Procedure to add all newly accessible devices after a channel is added ****/
add_devices:
     proc (channel_idx, code);

dcl	channel_idx	   fixed bin parameter;
dcl	code		   fixed bin (35) parameter;

dcl	device_idx	   fixed bin;

	do device_idx = lbound (device_table.device_entry, 1) to hbound (device_table.device_entry, 1);
	     if newly_accessible (device_idx, channel_idx) then do;
		call add_device (device_idx, code);
		if code ^= 0 then do;
		     if add_all_sw then do;
			call ssu_$print_message (sci_ptr, code, "Adding device ^a.",
			     device_table.device_entry (device_idx).name);
			code = 0;			/* continue.. */
		     end;
		     else return;
		end;
		else if message_is_called_for () then
		     call ioa_ ("Added device ^a.", device_table.device_entry (device_idx).name);
	     end;
	end;

/* Funtion to determine whether a device d is being made accessible by the addition of channel c.
   For non-disks, this is true if no path other than channel c currently exists to device d.  For
   disks, we insist that two paths be available (to allow IOI and disk_control to peacefully coexist). */

newly_accessible:
	proc (d, c) returns (bit (1) aligned);

dcl	d		   fixed bin parameter;
dcl	c		   fixed bin parameter;

dcl	path_count	   fixed bin;

	     if device_table.device_entry (d).configured then
		return ("0"b);			/* it's previously accessible */
	     path_count = available_paths (d);
	     if device_type (d) = "dsk" then
		return ((path_count = 2) & connected (c, d));
	     else return ((path_count = 1) & connected (c, d));

	end newly_accessible;

     end add_devices;

/**** Procedure to delete all devices which are only accessible via a given channel */
delete_devices:
     proc (channel_idx, code);

dcl	channel_idx	   fixed bin parameter;
dcl	code		   fixed bin (35) parameter;

dcl	device_idx	   fixed bin;

	code = 0;
	do device_idx = lbound (device_table.device_entry, 1) to hbound (device_table.device_entry, 1);
	     if needs_this_channel (device_idx, channel_idx) then do;
		call delete_device (device_idx, code);
		if code ^= 0 then
		     return;
		if message_is_called_for () then
		     call ioa_ ("Removed device ^a.", device_table.device_entry (device_idx).name);
	     end;
	end;

/* Function which decides if device d requires channel c.  The rules are the inverse of newly_accessible above. */

needs_this_channel:
	proc (d, c) returns (bit (1) aligned);

dcl	d		   fixed bin parameter;
dcl	c		   fixed bin parameter;

dcl	path_count	   fixed bin;

	     if ^device_table.device_entry (d).configured then
		return ("0"b);

	     path_count = available_paths (d);
	     if device_type (d) = "dsk" then
		return ((path_count = 2) & connected (c, d));
	     else return ((path_count = 1) & connected (c, d));

	end needs_this_channel;

     end delete_devices;

canonicalize_channel_name:
     proc (name);

dcl	name		   char (*) parameter;

canonicalize_iom_name:
     entry (name);

	name = translate (name, "ABCD", "abcd");
	return;

     end canonicalize_channel_name;

base_channel:
     proc (idx) returns (bit (1) aligned);

dcl	idx		   fixed bin parameter;

	return (channel_table.channel_entry (idx).base_channel_idx = idx);

     end base_channel;

device_type:
     proc (d) returns (char (3));

dcl	d		   fixed bin parameter;

	return (substr (device_table.device_entry (d).name, 1, 3));

     end device_type;

/**** Function which counts the number of currently available channels to a given device ****/
available_paths:
     proc (d) returns (fixed bin);

dcl	d		   fixed bin parameter;	/* device index */

dcl	c		   fixed bin;		/* channel index */
dcl	count		   fixed bin;

	count = 0;
	do c = lbound (channel_table.channel_entry, 1) to hbound (channel_table.channel_entry, 1);
	     if channel_table.channel_entry (c).configured & connected (c, d) then
		count = count + 1;
	end;
	return (count);

     end available_paths;

connected:
     proc (c, d) returns (bit (1) aligned);

dcl	c		   fixed bin parameter;
dcl	d		   fixed bin parameter;

dcl	i		   fixed bin;

	do i = lbound (null () -> device_entry_template.pchan_idx, 1)
	     to hbound (null () -> device_entry_template.pchan_idx, 1)
	     while (device_table.device_entry (d).pchan_idx (i) ^= 0);
	     if channel_table.channel_entry (c).base_channel_idx = device_table.device_entry (d).pchan_idx (i) then
		return ("1"b);
	end;
	return ("0"b);

     end connected;

ACTION_LABEL (6):					/* physical channels */
	call setup_io_config_ptrs;
	call canonicalize_channel_name (name);
	do channel_idx = lbound (channel_table.channel_entry, 1) to hbound (channel_table.channel_entry, 1)
	     while (name ^= channel_table.channel_entry (channel_idx).name);
	end;
	if channel_idx > hbound (channel_table.channel_entry, 1) then
	     call quit (error_table_$io_not_defined, "Channel ^a.", name);
	if ^base_channel (channel_idx) then
	     call quit (error_table_$not_base_channel, "Channel ^a.", name);

	if add_del_sw = ADD then
	     call add_physical_channel (channel_idx, code);
	else call delete_physical_channel (channel_idx, brief_sw, code);
	if code ^= 0 then
	     call quit (code, "Physical channel ^a.", name);
	if ^brief_sw then
	     call ioa_ ("^[Added^;Removed^] physical channel ^a.", add_del_sw = ADD, name);
	goto DONE;

add_physical_channel:
     proc (pc_idx, code);

dcl	pc_idx		   fixed bin parameter;
dcl	code		   fixed bin (35) parameter;

dcl	cx		   fixed bin;

	call add_channel (pc_idx, code);
	if code ^= 0 then
	     return;
	do cx = lbound (channel_table.channel_entry, 1) to hbound (channel_table.channel_entry, 1);
	     if (^base_channel (cx)) & (channel_table.channel_entry (cx).base_channel_idx = pc_idx) then
		call add_channel (cx, (0));		/* we'll let errors get reported, but we'll keep going */
	end;

     end add_physical_channel;

delete_physical_channel:
     proc (pc_idx, ignore_sw, code);

dcl	pc_idx		   fixed bin parameter;
dcl	ignore_sw		   bit (1) aligned parameter;
dcl	code		   fixed bin (35) parameter;

dcl	cx		   fixed bin;

	do cx = lbound (channel_table.channel_entry, 1) to hbound (channel_table.channel_entry, 1);
	     if (^base_channel (cx)) & (channel_table.channel_entry (cx).base_channel_idx = pc_idx)
		& (channel_table.channel_entry (cx).configured) then
		call delete_channel (cx, (0));	/* if one of these fails, so will the base */
	end;
	call delete_channel (pc_idx, code);
	if ignore_sw then
	     code = 0;

     end delete_physical_channel;

ACTION_LABEL (7):					/* MPC */
	call setup_io_config_ptrs;
	do mpc_idx = lbound (controller_table.controller_entry, 1)
	     to hbound (controller_table.controller_entry, 1)
	     while (controller_table.controller_entry (mpc_idx).name ^= name);
	end;
	if mpc_idx > hbound (controller_table.controller_entry, 1) then
	     call quit (error_table_$io_not_defined, "Controller ^a.", name);

	code = 0;
	do channel_idx = lbound (channel_table.channel_entry, 1) to hbound (channel_table.channel_entry, 1);
	     if (base_channel (channel_idx)) & (channel_table.channel_entry (channel_idx).controller_idx = mpc_idx)
	     then do;
		if add_del_sw = ADD then
		     call add_physical_channel (channel_idx, code);
		else if channel_table.channel_entry (channel_idx).configured then
		     call delete_physical_channel (channel_idx, brief_sw, code);
		if code ^= 0 then
		     call quit (code, "Controller ^a.", name);
	     end;
	end;
	if ^brief_sw then
	     call ioa_ ("^[Added^;Removed^] MPC ^a.", add_del_sw = ADD, name);
	goto DONE;

ACTION_LABEL (8):					/* IOMs */
	call setup_io_config_ptrs;
	call canonicalize_iom_name (name);
	do iom_idx = lbound (iom_table.iom_entry, 1) to hbound (iom_table.iom_entry, 1)
	     while (iom_table.iom_entry (iom_idx).name ^= name);
	end;
	if iom_idx > hbound (iom_table.iom_entry, 1) then
	     call quit (error_table_$io_not_defined, "IOM ^a.", name);

	if add_del_sw = ADD then do;
	     call add_iom (iom_idx, code);
	     if code ^= 0 then
		call quit (code, "IOM ^a.", name);
	end;

	if add_all_sw | delete_all_sw then
	     do channel_idx = lbound (channel_table.channel_entry, 1) to hbound (channel_table.channel_entry, 1);
	     if (base_channel (channel_idx)) & (iom_idx = channel_table.channel_entry (channel_idx).iom_idx) then do;
		if add_del_sw = ADD then
		     call add_physical_channel (channel_idx, code);
		else do;
		     call delete_physical_channel (channel_idx, brief_sw, code);
		     if code = error_table_$chnl_already_deleted then
			code = 0;
		end;
		if code ^= 0 then
		     call quit (code, "Channel ^a.", channel_table.channel_entry (channel_idx).name);
	     end;
	end;

	if add_del_sw ^= ADD then do;
	     call delete_iom (iom_idx, code);
	     if code ^= 0 then
		call quit (code, "IOM ^a.", name);
	end;

	if message_is_called_for () then
	     call ioa_ ("^[Added^;Removed^] IOM ^a.", add_del_sw = ADD, name);
	goto DONE;

add_iom:
     proc (idx, code);

dcl	idx		   fixed bin parameter;
dcl	code		   fixed bin (35) parameter;

	call hphcs_$add_iom (get_tag_from_name ((iom_table.iom_entry (idx).name)), code);
	goto add_delete_iom_common;

delete_iom:
     entry (idx, code);

	call hphcs_$delete_iom (get_tag_from_name ((iom_table.iom_entry (idx).name)), code);

add_delete_iom_common:
	if code = 0 then
	     call add_to_backout_list (idx, "iom");
	return;

     end add_iom;

ERROR_RETURN:
	call backout_work_so_far;
DONE:
	call clean_up;

	return;

clean_up: proc;

	if cdtp ^= null () then do;
	     call terminate_file_ (cdtp, (0), TERM_FILE_TERM, (0));
	     cdtp = null ();
	end;
	if area_ptr ^= null () then do;
	     call ssu_$release_area (sci_ptr, area_ptr);
	     area_ptr =null ();
	end;
	if standalone_invocation then do;
	     call ssu_$destroy_invocation (sci_ptr);
	     sci_ptr = null ();
	end;
     end clean_up;

add_to_backout_list:
     proc (idx, type);

dcl	idx		   fixed bin;
dcl	type		   char (*) parameter;

	if backing_out then
	     return;				/* avoid looping */
	allocate backout_item in (area) set (item_ptr);
	backout_item.idx = idx;
	backout_item.type = type;
	backout_item.next_item = backout_list_ptr;
	backout_list_ptr = item_ptr;

     end add_to_backout_list;

backout_work_so_far:
     proc;

dcl	name		   char (32);

	backing_out = "1"b;
	if add_del_sw = ADD then do;
	     delete_all_sw = add_all_sw;
	     add_all_sw = "0"b;
	end;
	else do;
	     add_all_sw = delete_all_sw;
	     delete_all_sw = "0"b;
	end;
	if backout_list_ptr = null () then
	     return;
	if ^brief_sw then
	     call ioa_ ("****    Restoring configuration.    ****");
	do while (backout_list_ptr ^= null ());
	     item_ptr = backout_list_ptr;
	     if backout_item.type = "iom" then do;
		name = iom_table.iom_entry (backout_item.idx).name;
		if add_del_sw = ADD then
		     call delete_iom (backout_item.idx, code);
		else call add_iom (backout_item.idx, code);
	     end;
	     else if backout_item.type = "channel" then do;
		name = channel_table.channel_entry (backout_item.idx).name;
		if add_del_sw = ADD then
		     call delete_channel (backout_item.idx, code);
		else call add_channel (backout_item.idx, code);
	     end;
	     else if backout_item.type = "device" then do;
		name = device_table.device_entry (backout_item.idx).name;
		if add_del_sw = ADD then
		     call delete_device (backout_item.idx, code);
		else call add_device (backout_item.idx, code);
	     end;
	     if code ^= 0 then
		call ssu_$print_message (sci_ptr, code, "Unable to back out ^[addition^;removal^] of ^a ^a.",
		     add_del_sw = ADD, backout_item.type, name);
	     backout_list_ptr = backout_item.next_item;
	end;

     end backout_work_so_far;

get_tag_from_name:
     proc (name) returns (fixed bin (3));

dcl	name		   char (*) parameter;

	return (index (TAGS_STRING, translate (rtrim (name), TAGS_STRING, TAGS_STRING_UPPER_CASE)));

     end get_tag_from_name;

setup_io_config_ptrs:
     proc;

	io_config_data_ptr = addr (io_config_data$);
	if io_config_data.version ^= IO_CONFIG_DATA_VERSION_1 then
	     call quit (error_table_$unimplemented_version, "io_config_data");
	io_config_device_table_ptr = ptr (io_config_data_ptr, io_config_data.device_table_offset);
	if device_table.version ^= IO_CONFIG_DEVICE_TABLE_VERSION_1 then
	     call quit (error_table_$unimplemented_version, "io_config_data.device_table");

	io_config_channel_table_ptr = ptr (io_config_data_ptr, io_config_data.channel_table_offset);
	if channel_table.version ^= IO_CONFIG_CHANNEL_TABLE_VERSION_1 then
	     call quit (error_table_$unimplemented_version, "io_config_data.channel_table");

	io_config_controller_table_ptr = ptr (io_config_data_ptr, io_config_data.controller_table_offset);
	if controller_table.version ^= IO_CONFIG_CONTROLLER_TABLE_VERSION_1 then
	     call quit (error_table_$unimplemented_version, "io_config_data.controller_table");

	io_config_iom_table_ptr = ptr (io_config_data_ptr, io_config_data.iom_table_offset);
	if iom_table.version ^= IO_CONFIG_IOM_TABLE_VERSION_1 then
	     call quit (error_table_$unimplemented_version, "io_config_data.iom_table");

     end setup_io_config_ptrs;

abort_entry:
     proc;

	goto ERROR_RETURN;

     end abort_entry;

quit_with_usage:
     proc (code);

dcl	code		   fixed bin (35) parameter;

	call quit (code, "Usage: reconfigure op type name {-control_args}");

     end quit_with_usage;

quit:
     proc options (variable);

dcl	arg_list_ptr	   ptr;
dcl	code		   fixed bin (35);
dcl	message		   char (128);

          call extract_code ("quit");
	if code = error_table_$io_not_configured then
	     call ioa_ ("Attempt to delete a device which is already deleted. ^a", name);
	else do;
	     call ioa_$general_rs (arg_list_ptr, 2, 3, message, (0), "1"b, "0"b);
	     call ssu_$abort_line (sci_ptr, code, message);
	end;
	goto ERROR_RETURN;

extract_code:
	proc (name);

dcl	name		   char (*) parameter;
dcl	fb35		   fixed bin (35) based;

	     call cu_$arg_list_ptr (arg_list_ptr);
	     if arg_list_ptr -> arg_list.arg_count < 1 then
		call quit (error_table_$noarg, "Internal programming error -- ^a called with no arguments.", name);
	     code = arg_list_ptr -> arg_list.arg_ptrs (1) -> fb35;

%include arg_list;

	end extract_code;

     end quit;

quit_if_rc_error:
     proc (code);

dcl	code		   fixed bin (35) parameter;

dcl	row_idx		   fixed bin;

/**** rc codes are strange.   If the code is less than twice hbound (rc_messages$rc_messages, 2) but greater than
      hbound (...), it's a generic error, and its text is gotten from row 0 of the array.  If it's in
      the range hbound (...), then we use the type of thing we're reconfiguring as a
      row index to get the text.  If it's non-zero and out of both ranges, we assume it's a standard status code. ****/

	if code = 0 then
	     return;

	if code > 2 * hbound (rc_messages$rc_messages, 2) then
	     call quit (code, name);
	else if code > hbound (rc_messages$rc_messages, 2) then
	     call quit (0, rc_messages$rc_messages (0, code - hbound (rc_messages$rc_messages, 2)), name, reason);
	else do;
	     if add_del_sw = ADD then
		row_idx = 2 * action - 1;
	     else row_idx = 2 * action;
	     call quit (0, rc_messages$rc_messages (row_idx, code), name, reason);
	end;

     end quit_if_rc_error;

/* Procedure which decides if a message should be printed.  It honors the -brief switch, and tries to avoid
   printing if it knows the message (or one like it) will be printed by ring 0. */

message_is_called_for:
     proc () returns (bit (1) aligned);

	if brief_sw then
	     return ("0"b);
	else if standalone_invocation then
	     return ("1"b);
	else return (^sc_subsystem_info.the_system_console);

     end message_is_called_for;

/**** The following code should be removed and undocumented as soon as we can find and fix all instances
      of problems which would leave the lock unlocked.  It's really gross. ****/

reconfigure$force_unlock:
     entry;

dcl	1 auto_rci	   aligned like rci;

dcl	hphcs_$rc_force_unlock entry;
dcl	hphcs_$reconfig_info   entry (ptr, fixed bin (35));

          standalone_invocation = "1"b;     
	area_ptr, backout_list_ptr, cdtp, sci_ptr,
	     sc_subsystem_info_ptr = null ();

	on cleanup begin;
	     call backout_work_so_far;
	     call clean_up;
	end;

	backing_out = "0"b;
	call ssu_$standalone_invocation (sci_ptr, ME, RCF_V1, null (), abort_entry, code);
	if code ^= 0 then do;
	     call com_err_ (code, ME, "Could not create ssu_ invocation.");
	     return;
	end;
	call ssu_$arg_count (sci_ptr, arg_count);
	if arg_count ^= 0 then
	     call quit (error_table_$too_many_args, "");

	call hphcs_$reconfig_info (addr (auto_rci), code);
	if code = 0 then
	     call ssu_$print_message (sci_ptr, 0, "Reconfiguration data not locked.");
	else call ssu_$print_message (sci_ptr, 0, "Reconfiguration data locked by ^a", auto_rci.locker_group_id);

	call hphcs_$rc_force_unlock;

	goto DONE;

%include rci;
%include scs;

%include io_config_data;
%page;
%include rcerr;
%page;
%include rsw;
%page;
%include sc_subsystem_info_;
%page;
%include terminate_file;

     end reconfigure;
  



		    reconfigure_rcp.pl1             11/15/82  1859.6rew 11/15/82  1522.7       21627



/* ***********************************************************
   *                                                         *
   * Copyright, (C) Honeywell Information Systems Inc., 1982 *
   *                                                         *
   * Copyright (c) 1972 by Massachusetts Institute of        *
   * Technology and Honeywell Information Systems, Inc.      *
   *                                                         *
   *********************************************************** */


reconfigure_rcp:  procedure;

/*	This program is an operator command that adds and deletes devices.
*	Created on 12/31/74 by Bill Silver.
*
*	This program has two entry points:
*	     1.	add_device    -	Add a deleted device back to the system.
*	     2.	del_device    -	Delete a device from the system.
*/

dcl	arg_len		fixed bin;	/* Length of device name argument. */
dcl	arg_ptr		ptr;		/* Pointer to device name argument. */
dcl	ecode		fixed bin(35);	/* error_table_ code. */

dcl	argument char(arg_len) based(arg_ptr);	/* Used to reference device name argument. */

dcl	com_err_		   entry  options(variable);
dcl	cu_$arg_ptr	   entry  (fixed bin,ptr,fixed bin,fixed bin(35));
dcl	rcp_sys_$add_device	   entry  (char(*),fixed bin(35));
dcl	rcp_sys_$delete_device entry  (char(*),fixed bin(35));
/*	*/
add_device:  entry;

/*	This entry is called to add a deleted device back to the system.
*/
	call cu_$arg_ptr (1,arg_ptr,arg_len,ecode);
	if   ecode ^= 0
	     then do;
		call com_err_ (ecode,"reconfigure_rcp","Error getting device name.");
		return;
	     end;

	call rcp_sys_$add_device (argument,ecode);
	if   ecode ^= 0
	     then call com_err_ (ecode,"reconfigure_rcp","Error adding device: ^a",argument);

	return;




del_device:  entry;

/*	This entry is called to delete a device from the system.
*	The device must be known to RCP, that is, it must be configured.
*	If the device is currently in use by some process that usage will be
*	terminated.  The device will not be assigned to any other process until
*	it is added again.
*/
	call cu_$arg_ptr (1,arg_ptr,arg_len,ecode);
	if   ecode ^= 0
	     then do;
		call com_err_ (ecode,"reconfigure_rcp","Error getting device name.");
		return;
	     end;

	call rcp_sys_$delete_device (argument,ecode);
	if   ecode ^= 0
	     then call com_err_ (ecode,"reconfigure_rcp","Error deleting device: ^a",argument);

	end  reconfigure_rcp;




		    bull_copyright_notice.txt       08/30/05  1008.4r   08/30/05  1007.3    00020025

                                          -----------------------------------------------------------


Historical Background

This edition of the Multics software materials and documentation is provided and donated
to Massachusetts Institute of Technology by Group Bull including Bull HN Information Systems Inc. 
as a contribution to computer science knowledge.  
This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology,
Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell Bull Inc., Groupe Bull
and Bull HN Information Systems Inc. to the development of this operating system. 
Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970),
renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership
of Professor Fernando Jose Corbato.Users consider that Multics provided the best software architecture for 
managing computer hardware properly and for executing programs. Many subsequent operating systems
incorporated Multics principles.
Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., 
as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. .

                                          -----------------------------------------------------------

Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without
fee is hereby granted,provided that the below copyright notice and historical background appear in all copies
and that both the copyright notice and historical background and this permission notice appear in supporting
documentation, and that the names of MIT, HIS, Bull or Bull HN not be used in advertising or publicity pertaining
to distribution of the programs without specific prior written permission.
    Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc.
    Copyright 2006 by Bull HN Information Systems Inc.
    Copyright 2006 by Bull SAS
    All Rights Reserved

