1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 io_reconfig:
32 proc ();
33
34
35
36 dcl p_chanid char (8) aligned;
37 dcl p_code fixed bin (35);
38 dcl p_tag fixed bin (3);
39
40
41
42 dcl added bit (1) aligned;
43 dcl adding_channel bit (1) aligned init ("0"b);
44
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
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
64
65 dcl (addr, bin, hbound, lbound, null, ptr, rel, substr, unspec)
66 builtin;
67
68
69
70 dcl cleanup condition;
71
72
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
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
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
140
141 call lock_for_reconfig;
142
143
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;
151 dtep = addr (ioi_data.dt (dtx));
152 if dte.in_use & ^dte.direct & dte.process_id ^= ""b then do;
153
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
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
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
196
197 if gte.disk_data_subsystem_idx ^= 0 then do;
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;
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
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
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);
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
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
262
263 call lock_for_reconfig;
264
265
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
278
279 call get_chnl_add_info (ctep, itep, base_chnl, iom_active);
280
281
282
283
284
285
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
298
299 state_changed = "1"b;
300 if gte.disk_data_subsystem_idx ^= 0 then do;
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;
307 call ioi_usurp_channels$unassign (gtep, code);
308 call quit_if_error;
309 end;
310 else if ^gte.mplex then do;
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
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
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
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;
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;
476 end;
477
478
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
582
583 dcl cptr ptr;
584 dcl ctx fixed bin;
585 dcl gptr ptr;
586 dcl my_base_rptr bit (18) aligned;
587
588
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
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
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
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
671
672 dcl i fixed bin;
673
674
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
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
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;