1 /****^  ***********************************************************
  2         *                                                         *
  3         * Copyright, (C) Honeywell Bull Inc., 1987                *
  4         *                                                         *
  5         * Copyright, (C) Honeywell Information Systems Inc., 1983 *
  6         *                                                         *
  7         *********************************************************** */
  8 
  9 /*  Add_channel and delete_channel entries written 5/83 by S. Krupp. */
 10 /*  add_iom and delete_iom entries written 3/84 by Chris Jones */
 11 /*  Modifed August 1984 by Chris Jones to fix "change ctep" bug in ensure_rpv_path */
 12 /*  Modified November 1984 by M. Pandolf to call iom_switches$validate during IOM addition */
 13 
 14 
 15 /****^  HISTORY COMMENTS:
 16   1) change(86-11-17,Farley), approve(86-11-20,MECR0002),
 17      audit(86-11-19,Fawcett), install(86-11-20,MR12.0-1222):
 18      Added check to delete_channel for active device assignments that require
 19      the channel. If one is found the operation is aborted.
 20   2) change(86-12-19,Farley), approve(86-12-19,MCR7587),
 21      audit(86-12-19,Fawcett), install(87-01-05,MR12.0-1253):
 22      Formal installation to close out above MECR0002.
 23   3) change(87-06-11,Lippard), approve(87-06-29,MCR7729),
 24      audit(87-07-08,Farley), install(87-08-06,MR12.1-1063):
 25      Modified cleanup handler to not unassign the channel from IOI if IOI
 26      was using it when we were called.
 27                                                    END HISTORY COMMENTS */
 28 
 29 
 30 /* format: style4,delnl,insnl,indattr,ifthen,dclind10 */
 31 io_reconfig:
 32      proc ();
 33 
 34 /* Parameter */
 35 
 36 dcl       p_chanid               char (8) aligned;          /* (I) name of the channel in question */
 37 dcl       p_code                 fixed bin (35);            /* (O) standard system status code */
 38 dcl       p_tag                  fixed bin (3);             /* (I) IOM tag */
 39 
 40 /* Automatic */
 41 
 42 dcl       added                  bit (1) aligned;
 43 dcl       adding_channel         bit (1) aligned init ("0"b);
 44                                                             /* Always init this. */
 45 dcl       base_chnl              bit (1) aligned;
 46 dcl       chanid                 char (8) aligned;
 47 dcl       chnl_required          bit (1) aligned;
 48 dcl       code                   fixed bin (35);
 49 dcl       cv_status_ptr          ptr;
 50 dcl       deleting_channel       bit (1) aligned init ("0"b);
 51                                                             /* Always init this. */
 52 dcl       device_active          bit (1) aligned;
 53 dcl       dtx                    fixed bin;
 54 dcl       grp_chnl_active        bit (1) aligned;
 55 dcl       iom_active             bit (1) aligned;
 56 dcl       locked                 bit (1) aligned init ("0"b);
 57 dcl       rel_chnl_active        bit (1) aligned;
 58 dcl       state_changed          bit (1) aligned init ("0"b);
 59 dcl       tag                    fixed bin (3);
 60 dcl       temp_base_chnl_ptr     ptr;
 61 dcl       usurped_channel        bit (1) aligned;
 62 
 63 /* Builtin */
 64 
 65 dcl       (addr, bin, hbound, lbound, null, ptr, rel, substr, unspec)
 66                                  builtin;
 67 
 68 /* Condition */
 69 
 70 dcl       cleanup                condition;
 71 
 72 /* Entries */
 73 
 74 dcl       config_$find_2         entry (char (4) aligned, fixed bin, ptr);
 75 dcl       config_$update         entry ();
 76 dcl       dctl$disk_inter        entry (fixed bin (35), fixed bin (3), bit (36) aligned);
 77 dcl       disk_control$add_channel
 78                                  entry (fixed bin (8), fixed bin (35), bit (1) aligned);
 79 dcl       ioi_assignment$lock_for_reconfig
 80                                  entry;
 81 dcl       ioi_assignment$unlock_for_reconfig
 82                                  entry;
 83 dcl       ioi_masked$interrupt   entry (fixed bin (35), fixed bin (3), bit (36) aligned);
 84 dcl       ioi_usurp_channels$assign
 85                                  entry (ptr, fixed bin (35));
 86 dcl       ioi_usurp_channels$required
 87                                  entry (ptr, fixed bin (35));
 88 dcl       ioi_usurp_channels$unassign
 89                                  entry (ptr, fixed bin (35));
 90 dcl       iom_overhead$init      entry (fixed bin (3), fixed bin (35));
 91 dcl       iom_overhead$release   entry (fixed bin (3), fixed bin (35));
 92 dcl       iom_switches$validate  entry (fixed bin (3), fixed bin (35));
 93 dcl       pxss$addevent          entry (bit (36) aligned);
 94 dcl       pxss$wait              entry ();
 95 dcl       scr_util$set_port_enable
 96                                  entry (fixed bin (3), bit (1) unal);
 97 dcl       syserr                 entry () options (variable);
 98 
 99 /* Static */
100 
101 dcl       (
102           error_table_$bad_channel,
103           error_table_$chnl_already_added,
104           error_table_$chnl_already_deleted,
105           error_table_$chnl_being_deleted,
106           error_table_$chnl_iom_active,
107           error_table_$chnl_iom_inactive,
108           error_table_$io_not_available,
109           error_table_$io_not_defined,
110           error_table_$iom_already_added,
111           error_table_$iom_already_deleted,
112           error_table_$no_base_chnl_active,
113           error_table_$rel_chnl_active,
114           error_table_$undeleted_device
115           )                      fixed bin (35) ext static;
116 
117 dcl       DUMMY_INDEX            fixed bin (35) init (0) int static options (constant);
118 ^L
119 delete_channel:
120      entry (p_chanid, p_code);
121 
122           deleting_channel = "1"b;
123           usurped_channel = "0"b;
124           idp = addr (ioi_data$);
125           io_config_data_ptr = addr (io_config_data$);
126           io_config_channel_table_ptr = ptr (io_config_data_ptr, io_config_data.channel_table_offset);
127           io_config_iom_table_ptr = ptr (io_config_data_ptr, io_config_data.iom_table_offset);
128 
129 /* Look in ioi_data for required info. */
130 
131           chanid = io_chnl_util$canonicalize_chanid (p_chanid);
132           call get_ctep (chanid, ctep, code);
133           call quit_if_error;
134 
135           call get_gtep (ctep, gtep);
136 
137           on cleanup call CLEANUP ();
138 
139 /* Lock for reconfiguration. */
140 
141           call lock_for_reconfig;
142 
143 /* Make some checks on state of channel and then mark it as being deleted. */
144 
145           if cte.deleted then
146                call ABORT (error_table_$chnl_already_deleted);
147           else if cte.deleting then
148                call ABORT (error_table_$chnl_being_deleted);
149 
150           do dtx = 1 to ioi_data.ndt;                       /* check if channel is required for an active device */
151                dtep = addr (ioi_data.dt (dtx));
152                if dte.in_use & ^dte.direct & dte.process_id ^= ""b then do;
153                                                             /* if IOI is managing this device and it is assigned... */
154                     if dte.channel_required = chanid then
155                          call ABORT (error_table_$io_not_available);
156                end;
157           end;
158 
159 
160           state_changed = "1"b;
161           cte.deleting = "1"b;
162 
163 /* Get information relevant to deleting a channel. */
164 
165           call get_chnl_del_info (gtep, ctep, base_chnl, rel_chnl_active, grp_chnl_active);
166           call get_device_info (gtep, ctep, device_active, chnl_required);
167 
168 /* Make sure it is legal to delete this channel.
169 
170    Rules:  The channel must not be in use.  The channel may not be
171    the only logical channel that can reach an as yet undeleted
172    device. If the channel is a base channel, then all logical
173    channels on the same physical channel must have been
174    previously deleted.
175 
176    Notes:  rel_chnl_active = true means that there are other active
177    channels that are on the same physical channel as chanid.
178 
179    grp_chnl_active = true means that there are other active
180    channels in the same group as chanid, but they are not
181    on the same physical channel as chanid.
182 
183    If chanid doesn't specify a base channel, then there is
184    always at least one channel around to handle active devices
185    if chanid is deleted.
186 */
187 
188           if base_chnl then do;
189                if rel_chnl_active then
190                     call ABORT (error_table_$rel_chnl_active);
191                if device_active & ^grp_chnl_active then
192                     call ABORT (error_table_$undeleted_device);
193           end;
194 
195 /* If channel doesn't belong to ioi, try to get it. */
196 
197           if gte.disk_data_subsystem_idx ^= 0 then do;      /* Have disk chnl.  Try to usurp it. */
198                if ^cte.ioi_use then do;
199                     call ioi_usurp_channels$required (ctep, code);
200                     call quit_if_error;
201                     usurped_channel = "1"b;
202                end;
203           end;
204           else if ^cte.ioi_use then do;                     /* Have non-ioi, non-disk type of chnl.  Try to grab it. */
205                call io_manager$assign (cte.chx, chanid, io_manager$ignore_interrupt, DUMMY_INDEX, cv_status_ptr, code);
206                call quit_if_error;
207                cte.ioi_use = "1"b;
208                usurped_channel = "1"b;
209           end;
210 
211 /* Wait for channel activity to clear. */
212 
213           do while (cte.connected);
214                call pxss$addevent (unspec (IO_CHANNEL_LOCK_TEMPLATE) || rel (ctep));
215                call pxss$wait ();
216           end;
217 
218 /* Delete the channel. */
219 
220           call io_manager$unassign_delete (cte.chx, code);
221           call quit_if_error;
222           cte.ioi_use = "0"b;
223           cte.deleted = "1"b;
224           cte.deleting = "0"b;
225           call ensure_rpv_path_in_toehold;
226           channel_table.channel_entry (cte.channel_table_idx).configured = "0"b;
227           iom_table.iom_entry (channel_table.channel_entry (cte.channel_table_idx).iom_idx).n_configured_channels =
228                iom_table.iom_entry (channel_table.channel_entry (cte.channel_table_idx).iom_idx).n_configured_channels
229                - 1;
230 
231           if gte.disk_data_subsystem_idx ^= 0 then do;
232                call ioi_usurp_channels$assign (gtep, code); /* make sure we still have enough */
233                call quit_if_error;
234           end;
235 
236           call unlock_for_reconfig;
237           call syserr (LOG, "RCF: Deleted channel ^a.", chanid);
238           p_code = 0;
239           return;
240 ^L
241 add_channel:
242      entry (p_chanid, p_code);
243 
244           adding_channel = "1"b;
245           idp = addr (ioi_data$);
246           io_config_data_ptr = addr (io_config_data$);
247           io_config_channel_table_ptr = ptr (io_config_data_ptr, io_config_data.channel_table_offset);
248           io_config_iom_table_ptr = ptr (io_config_data_ptr, io_config_data.iom_table_offset);
249 
250 /* Look in ioi_data for required info. */
251 
252           chanid = io_chnl_util$canonicalize_chanid (p_chanid);
253           call get_ctep (chanid, ctep, code);
254           call quit_if_error;
255 
256           call get_gtep (ctep, gtep);
257           call get_itep (ctep, itep);
258 
259           on cleanup call CLEANUP ();
260 
261 /* Lock for reconfiguration. */
262 
263           call lock_for_reconfig;
264 
265 /* Make some checks on state of channel. */
266 
267           if ^cte.deleted then do;
268                if (^cte.ioi_use) & (gte.disk_data_subsystem_idx ^= 0) then
269                     call disk_control$add_channel ((gte.disk_data_subsystem_idx), (cte.disktab_ctx), added);
270                if added then
271                     goto DONE_ADDING;
272                call ABORT (error_table_$chnl_already_added);
273           end;
274           else if cte.deleting then
275                call ABORT (error_table_$chnl_being_deleted);
276 
277 /* Get information relevant to adding a channel. */
278 
279           call get_chnl_add_info (ctep, itep, base_chnl, iom_active);
280 
281 /* Make sure it is legal to add this channel.
282 
283    Rules:  The channel must be connected to an active iom.  If the channel
284    is not a base channel, its associated base channel must already
285    be active.
286 */
287 
288           if ^iom_active then
289                call ABORT (error_table_$chnl_iom_inactive);
290 
291           if ^base_chnl then do;
292                temp_base_chnl_ptr = ptr (ctep, cte.base_ctep);
293                if temp_base_chnl_ptr -> cte.deleted then
294                     call ABORT (error_table_$no_base_chnl_active);
295           end;
296 
297 /* If channel belonged to someone else originally, give it back. */
298 
299           state_changed = "1"b;
300           if gte.disk_data_subsystem_idx ^= 0 then do;      /* Have disk chnl. */
301                call io_manager$assign_add (cte.chx, chanid, dctl$disk_inter,
302                     dskdcl_chans_per_subsys * gte.disk_data_subsystem_idx + cte.disktab_ctx - 1, cv_status_ptr, code);
303                call quit_if_error;
304                cte.statusp = cv_status_ptr;
305                cte.deleted = "0"b;
306                cte.ioi_use = "1"b;                          /* so it will be given back */
307                call ioi_usurp_channels$unassign (gtep, code);
308                call quit_if_error;
309           end;
310           else if ^gte.mplex then do;                       /* Have non-ioi, non-disk type of chnl. */
311                call io_manager$assign_add (cte.chx, chanid, io_manager$ignore_interrupt, DUMMY_INDEX, cv_status_ptr, code)
312                     ;
313                call quit_if_error;
314                cte.deleted = "0"b;
315                call io_manager$unassign (cte.chx, code);
316                call quit_if_error;
317           end;
318           else do;
319                call io_manager$assign_add (cte.chx, chanid, ioi_masked$interrupt, bin (rel (ctep)), cv_status_ptr, code);
320                call quit_if_error;
321                cte.deleted = "0"b;
322                cte.ioi_use = "1"b;
323           end;
324 
325           channel_table.channel_entry (cte.channel_table_idx).configured = "1"b;
326           iom_table.iom_entry (channel_table.channel_entry (cte.channel_table_idx).iom_idx).n_configured_channels =
327                iom_table.iom_entry (channel_table.channel_entry (cte.channel_table_idx).iom_idx).n_configured_channels
328                + 1;
329           call syserr (LOG, "RCF: Added channel ^a.", chanid);
330 
331 DONE_ADDING:
332           call unlock_for_reconfig;
333           p_code = 0;
334 
335           return;
336 
337 ERROR_RETURN:
338           return;
339 ^L
340 add_iom:
341      entry (p_tag, p_code);
342 
343           call setup_and_find_iom_entry;
344           call lock_for_reconfig;
345           if iom_table.iom_entry (ite.iom_table_idx).configured then do;
346                call unlock_for_reconfig;
347                p_code = error_table_$iom_already_added;
348                return;
349           end;
350           iom_data.per_iom (tag).on_line = "1"b;
351           call iom_overhead$init (tag, code);
352           if code ^= 0 then do;
353                iom_data.per_iom (tag).on_line = "0"b;
354                call unlock_for_reconfig;
355                p_code = code;
356                return;
357           end;
358           call scr_util$set_port_enable (iom_card.port, "1"b);
359                                                             /* allow all SCUs at the IOM */
360 
361           call iom_switches$validate (tag, code);
362           if code ^= 0 then
363                call syserr (CRASH, "io_reconfig: Unable to validate switches for IOM ^a.", substr ("abcd", tag, 1));
364 
365           ite.deleted = "0"b;
366           iom_table.iom_entry (ite.iom_table_idx).configured = "1"b;
367           iom_card.state = "on";
368           call config_$update;
369           call unlock_for_reconfig;
370           call syserr (ANNOUNCE, "RCF: Added IOM ^a.", substr ("abcd", tag, 1));
371           p_code = 0;
372           return;
373 ^L
374 delete_iom:
375      entry (p_tag, p_code);
376 
377           call setup_and_find_iom_entry;
378           call lock_for_reconfig;
379           if iom_table.iom_entry (ite.iom_table_idx).n_configured_channels ^= 0 then do;
380                call unlock_for_reconfig;
381                p_code = error_table_$chnl_iom_active;
382                return;
383           end;
384           if ^iom_table.iom_entry (ite.iom_table_idx).configured then do;
385                call unlock_for_reconfig;
386                p_code = error_table_$iom_already_deleted;
387                return;
388           end;
389 
390           call iom_overhead$release (tag, code);
391           if code ^= 0 then do;
392                call unlock_for_reconfig;
393                p_code = code;
394                return;
395           end;
396 
397           call scr_util$set_port_enable (iom_card.port, "0"b);
398                                                             /* disable all SCU's access to this IOM */
399           ite.deleted = "1"b;
400           iom_table.iom_entry (ite.iom_table_idx).configured = "0"b;
401           iom_data.per_iom (tag).on_line = "0"b;
402           iom_card.state = "off";
403           call config_$update;
404           call unlock_for_reconfig;
405           call syserr (ANNOUNCE, "RCF: Deleted IOM ^a.", substr ("abcd", tag, 1));
406           p_code = 0;
407           return;
408 ^L
409 setup_and_find_iom_entry:
410      proc;
411 
412 dcl       itx                    fixed bin;
413 
414           tag = p_tag;
415           iom_cardp = null ();
416           call config_$find_2 (IOM_CARD_WORD, (tag), iom_cardp);
417           if iom_cardp = null () then
418                goto IOM_NOT_CONFIGURED;
419 
420           idp = addr (ioi_data$);
421           iom_data_ptr = addr (iom_data$);
422           io_config_data_ptr = addr (io_config_data$);
423           io_config_iom_table_ptr = ptr (io_config_data_ptr, io_config_data.iom_table_offset);
424           do itx = lbound (ioi_data.it, 1) to hbound (ioi_data.it, 1);
425                itep = addr (ioi_data.it (itx));
426                if tag = ite.tag then
427                     return;
428           end;
429 
430 IOM_NOT_CONFIGURED:
431           p_code = error_table_$io_not_defined;
432           goto ERROR_RETURN;
433 
434      end setup_and_find_iom_entry;
435 ^L
436 /* Procedure to ensure that the toehold has a non-deleted path to RPV when deleting a channel. */
437 
438 ensure_rpv_path_in_toehold:
439      proc;
440 
441 dcl       iomno                  fixed bin (3);
442 dcl       channo                 fixed bin (7);
443 dcl       iopx                   fixed bin;
444 dcl       saved_ctep             ptr;
445 dcl       saved_iopx             fixed bin;
446 dcl       toehold_channel_left   bit (1) aligned;
447 
448 dcl       1 path_word            aligned,
449             2 port               fixed bin (3) uns unal,
450             2 iom                fixed bin (15) uns unal,
451             2 channel            fixed bin unal;
452 
453 dcl       path_word_as_integer   fixed bin (35) based (addr (path_word));
454 
455 dcl       1 toehold$             ext like toe_hold;
456 
457           call io_chnl_util$name_to_iom (cte.chanid, iomno, channo, (0));
458 
459           do iopx = lbound (toehold$.paths, 1) to hbound (toehold$.paths, 1);
460                if (toehold$.paths (iopx).iom_number = iomno) & (toehold$.paths (iopx).channel_number = channo) then
461                     goto FOUND_TOEHOLD_CHANNEL;
462           end;
463           return;                                           /* no problem since toehold doesn't use this channel */
464 
465 FOUND_TOEHOLD_CHANNEL:
466           saved_iopx = iopx;
467           toehold_channel_left = "0"b;
468           do iopx = lbound (toehold$.paths, 1) to hbound (toehold$.paths, 1) while (^toehold_channel_left);
469                if iopx ^= saved_iopx then
470                     if toehold$.paths (iopx).channel_number ^= 0 then
471                          toehold_channel_left = "1"b;
472           end;
473           if toehold_channel_left then do;
474                call set_toehold_path (saved_iopx, 0);
475                return;                                      /* not to worry */
476           end;
477 
478 /**** We must find another channel and put it in the toehold ****/
479 
480           saved_ctep = ctep;
481           do ctep = ptr (ctep, ptr (ctep, cte.gtep) -> gte.ctep) repeat ptr (ctep, cte.next_ctep)
482                while (cte.deleted | cte.deleting | (cte.base_ctep ^= rel (ctep)));
483           end;
484           call io_chnl_util$name_to_iom (cte.chanid, iomno, channo, (0));
485           call config_$find_2 (IOM_CARD_WORD, (iomno), iom_cardp);
486           path_word.port = iom_card.port;
487           path_word.iom = iomno;
488           path_word.channel = channo;
489           call set_toehold_path (saved_iopx, path_word_as_integer);
490           ctep = saved_ctep;
491           return;
492 
493 set_toehold_path:
494           proc (path_idx, path_word_value);
495 
496 dcl       path_idx               fixed bin;
497 dcl       path_word_value        fixed bin (35);
498 dcl       path_word_ptr          ptr;
499 
500 dcl       path_word              fixed bin (35) based (path_word_ptr);
501 
502                path_word_ptr = addr (toehold$.paths (path_idx).port_number);
503                path_word = path_word_value;
504 
505           end set_toehold_path;
506 
507      end ensure_rpv_path_in_toehold;
508 ^L
509 quit_if_error:
510      proc;
511 
512           if code ^= 0 then
513                call ABORT (code);
514 
515      end quit_if_error;
516 
517 ABORT:
518      proc (a_code);
519 
520 dcl       a_code                 fixed bin (35);
521 
522           call CLEANUP ();
523           p_code = a_code;
524           goto ERROR_RETURN;
525 
526      end ABORT;
527 
528 
529 CLEANUP:
530      proc ();
531 
532           if (gtep ^= null ()) & (ctep ^= null ()) & (state_changed) then do;
533                if deleting_channel then do;
534                     if usurped_channel then do;
535                          if gte.disk_data_subsystem_idx > 0 then
536                               call ioi_usurp_channels$unassign (gtep, (0));
537                          else if ^gte.mplex & cte.chx > 0 then do;
538                               call io_manager$unassign (cte.chx, (0));
539                               cte.ioi_use = "0"b;
540                          end;
541                     end;
542                     cte.deleted = "0"b;
543                     cte.deleting = "0"b;
544                end;
545                else if adding_channel then do;
546                     if gte.disk_data_subsystem_idx ^= 0 then
547                          call ioi_usurp_channels$assign (gtep, code);
548                     else if ^gte.mplex & cte.chx > 0 then do;
549                          call io_manager$assign (cte.chx, chanid, io_manager$ignore_interrupt, DUMMY_INDEX, cv_status_ptr,
550                               code);
551                          if code = 0 then
552                               cte.statusp = cv_status_ptr;
553                     end;
554                     cte.deleted = "1"b;
555                end;
556           end;
557           if locked then
558                call ioi_assignment$unlock_for_reconfig;
559 
560      end CLEANUP;
561 
562 lock_for_reconfig:
563      proc;
564 
565           call ioi_assignment$lock_for_reconfig;
566           locked = "1"b;
567 
568      end lock_for_reconfig;
569 
570 unlock_for_reconfig:
571      proc;
572 
573           call ioi_assignment$unlock_for_reconfig;
574           locked = "0"b;
575 
576      end unlock_for_reconfig;
577 ^L
578 get_chnl_del_info:
579      proc (arg_gtep, arg_ctep, arg_base_chnl, arg_rel_chnl_active, arg_grp_chnl_active);
580 
581 /* Automatic */
582 
583 dcl       cptr                   ptr;
584 dcl       ctx                    fixed bin;
585 dcl       gptr                   ptr;
586 dcl       my_base_rptr           bit (18) aligned;
587 
588 /* Parameter */
589 
590 dcl       arg_base_chnl          bit (1) aligned;
591 dcl       arg_ctep               ptr;
592 dcl       arg_grp_chnl_active    bit (1) aligned;
593 dcl       arg_gtep               ptr;
594 dcl       arg_rel_chnl_active    bit (1) aligned;
595 
596           arg_rel_chnl_active, arg_grp_chnl_active = "0"b;
597           arg_base_chnl = (arg_ctep -> cte.base_ctep = rel (arg_ctep));
598 
599           my_base_rptr = arg_ctep -> cte.base_ctep;
600           gptr = arg_gtep;
601 
602           do ctx = 1 to ioi_data.nct;
603                cptr = addr (ioi_data.ct (ctx));
604                if ^(cptr -> cte.deleted | cptr = arg_ctep) then do;
605                     if cptr -> cte.base_ctep = my_base_rptr then
606                          arg_rel_chnl_active = "1"b;
607                     else if cptr -> cte.gtep = rel (gptr) then
608                          arg_grp_chnl_active = "1"b;
609                end;
610           end;
611 
612      end get_chnl_del_info;
613 ^L
614 get_chnl_add_info:
615      proc (arg_ctep, arg_itep, arg_base_chnl, arg_iom_active);
616 
617 /* Parameter */
618 
619 dcl       arg_base_chnl          bit (1) aligned;
620 dcl       arg_ctep               ptr;
621 dcl       arg_iom_active         bit (1) aligned;
622 dcl       arg_itep               ptr;
623 
624           if ^arg_itep -> ite.deleted then
625                arg_iom_active = "1"b;
626           else arg_iom_active = "0"b;
627 
628           arg_base_chnl = (arg_ctep -> cte.base_ctep = rel (arg_ctep));
629 
630      end get_chnl_add_info;
631 ^L
632 get_device_info:
633      proc (arg_gtep, arg_ctep, arg_device_active, arg_chnl_required);
634 
635 /* Automatic */
636 
637 dcl       chanid                 char (8) aligned;
638 dcl       done                   bit (1) aligned;
639 dcl       dptr                   ptr;
640 dcl       gptr                   ptr;
641 dcl       initial_dtep           bit (18);
642 
643 /* Parameter */
644 
645 dcl       arg_chnl_required      bit (1) aligned;
646 dcl       arg_ctep               ptr;
647 dcl       arg_device_active      bit (1) aligned;
648 dcl       arg_gtep               ptr;
649 
650           arg_device_active, arg_chnl_required = "0"b;
651           chanid = arg_ctep -> cte.chanid;
652           gptr = arg_gtep;
653 
654           initial_dtep = gptr -> gte.dtep;
655           done = "0"b;
656           do dptr = ptr (arg_ctep, initial_dtep) repeat ptr (dptr, dptr -> dte.next_dtep) while (^done);
657                if ^(dptr -> dte.deleted) then do;
658                     arg_device_active = "1"b;
659                     if dptr -> dte.channel_required = chanid then
660                          arg_chnl_required = "1"b;
661                end;
662                done = (dptr -> dte.next_dtep = initial_dtep);
663           end;
664 
665      end get_device_info;
666 ^L
667 get_ctep:
668      proc (arg_chanid, arg_ctep, arg_code);
669 
670 /* Automatic */
671 
672 dcl       i                      fixed bin;
673 
674 /* Parameter */
675 
676 dcl       arg_chanid             char (8) aligned;
677 dcl       arg_code               fixed bin (35);
678 dcl       arg_ctep               ptr;
679 
680           arg_ctep = null;
681           arg_code = 0;
682 
683           do i = 1 to ioi_data.nct;
684                if ioi_data.ct (i).chanid = arg_chanid then do;
685                     arg_ctep = addr (ioi_data.ct (i));
686                     return;
687                end;
688           end;
689 
690           arg_code = error_table_$bad_channel;
691 
692      end get_ctep;
693 
694 
695 get_gtep:
696      proc (arg_ctep, arg_gtep);
697 
698 /* Parameter */
699 
700 dcl       arg_ctep               ptr;
701 dcl       arg_gtep               ptr;
702 
703           arg_gtep = ptr (arg_ctep, arg_ctep -> cte.gtep);
704 
705      end get_gtep;
706 
707 
708 get_itep:
709      proc (arg_ctep, arg_itep);
710 
711 /* Parameter */
712 
713 dcl       arg_ctep               ptr;
714 dcl       arg_itep               ptr;
715 
716           arg_itep = ptr (arg_ctep, arg_ctep -> cte.itep);
717 
718      end get_itep;
719 ^L
720 %include config_iom_card;
721 %page;
722 %include dskdcl;
723 %page;
724 %include ioi_data;
725 %page;
726 %include io_config_data;
727 %page;
728 %include io_manager_dcls;
729 %page;
730 %include io_chnl_util_dcls;
731 %page;
732 %include iom_data;
733 %page;
734 %include syserr_constants;
735 %page;
736 %include toe_hold;
737 
738      end io_reconfig;