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
32 ioi_init:
33 procedure;
34
35 dcl adding_controller_dte bit (1);
36 dcl chanid char (8) aligned;
37 dcl code fixed bin (35);
38 dcl ctx fixed bin;
39 dcl device_number fixed bin;
40 dcl device_type char (4);
41 dcl gtx fixed bin;
42 dcl itx fixed bin;
43 dcl high_ctx fixed bin;
44 dcl high_dtx fixed bin;
45 dcl high_gtx fixed bin;
46 dcl high_itx fixed bin;
47 dcl statusp ptr;
48 dcl iom_model_array (8) char (4) aligned;
49
50
51 dcl config_$find entry (char (4) aligned, ptr);
52 dcl ioi_config$find_base_channel
53 entry (char (8) aligned) returns (char (8) aligned);
54 dcl ioi_config$find_controller_card
55 entry (char (8) aligned) returns (ptr);
56 dcl ioi_masked$interrupt entry (fixed bin (35), fixed bin (3), bit (36) aligned);
57 dcl ioi_page_table$init entry;
58 dcl syserr entry options (variable);
59 dcl syserr$error_code entry options (variable);
60
61 dcl ME char (32) static options (constant) init ("ioi_init");
62
63 dcl (addr, bin, bit, divide, hbound, lbound, max, min, null, ptr, rel, string, substr, unspec)
64 builtin;
65 ^L
66 idp = addr (ioi_data$);
67 io_config_data_ptr = addr (io_config_data$);
68 io_config_iom_table_ptr = ptr (io_config_data_ptr, io_config_data.iom_table_offset);
69 io_config_controller_table_ptr = ptr (io_config_data_ptr, io_config_data.controller_table_offset);
70 io_config_channel_table_ptr = ptr (io_config_data_ptr, io_config_data.channel_table_offset);
71 io_config_device_table_ptr = ptr (io_config_data_ptr, io_config_data.device_table_offset);
72 disksp = addr (disk_seg$);
73
74 high_ctx, high_dtx, high_gtx, high_itx = 0;
75
76 iom_model_array (*) = "";
77 iom_cardp = null ();
78 call config_$find (IOM_CARD_WORD, iom_cardp);
79 do while (iom_cardp ^= null ());
80 high_itx = high_itx + 1;
81 itep = addr (ioi_data.it (high_itx));
82 unspec (ite) = ""b;
83 ite.tag = iom_card.tag;
84 ite.model = iom_card.model;
85 iom_model_array (ite.tag) = iom_card.model;
86 ite.deleted = (iom_card.state = "off");
87 ite.iom_table_idx = iom_table_idx_from_tag (ite.tag);
88 call config_$find (IOM_CARD_WORD, iom_cardp);
89 end;
90
91 prph_cardp = null ();
92 call config_$find (PRPH_CARD_WORD, prph_cardp);
93 do while (prph_cardp ^= null ());
94 device_type = substr (prph_card.name, 1, 3);
95 prph_dsk_cardp, prph_tap_cardp = prph_cardp;
96 call allocate_gte (prph_card.name);
97
98 if (device_type = "dsk") | (device_type = "tap") then
99 gte.mplex = "1"b;
100 call io_chnl_util$iom_to_name (prph_card.iom, (prph_card.chan), chanid, code);
101 if code ^= 0 then
102 call syserr$error_code (CRASH, code, "^a: Unable to get the name of iom ^d channel ^d.", ME,
103 prph_card.iom, prph_card.chan);
104 gte.ipc = IS_ON_IMU (prph_card.iom);
105 mpc_cardp = ioi_config$find_controller_card (chanid);
106 if mpc_cardp ^= null () then do;
107 gte.psia = "1"b;
108 ipc_cardp = mpc_cardp;
109 gte.fips = (ipc_card.word = IPC_CARD_WORD) & (ipc_card.type = IPC_FIPS);
110 end;
111 gte.detailed_status_cmd = extended_status_command ();
112 gte.ascii_dtst = ascii_detailed_status ();
113 call setup_log_status_info;
114 call allocate_dtes_from_prph_card;
115 call allocate_ctes_from_prph_card;
116 call config_$find (PRPH_CARD_WORD, prph_cardp);
117
118 end;
119
120
121
122 chnl_cardp = null ();
123 call config_$find (CHNL_CARD_WORD, chnl_cardp);
124 do while (chnl_cardp ^= null ());
125 device_type = substr (chnl_card.name, 1, 3);
126 if find_gte () then
127 call allocate_ctes_from_chnl_card;
128 call config_$find (CHNL_CARD_WORD, chnl_cardp);
129 end;
130
131
132
133 do ctx = lbound (ioi_data.ct, 1) to hbound (ioi_data.ct, 1);
134 ctep = addr (ioi_data.ct (ctx));
135 chanid = ioi_config$find_base_channel (cte.chanid);
136 cte.base_ctep = cte_offset (chanid);
137 if cte.base_ctep = ""b then
138 cte.base_ctep = rel (ctep);
139 end;
140
141
142
143 do gtx = lbound (ioi_data.gt, 1) to hbound (ioi_data.gt, 1);
144 gtep = addr (ioi_data.gt (gtx));
145 device_type = substr (gte.name, 1, 3);
146 if device_type = "dsk" then
147 call setup_disk_sharing;
148 end;
149
150
151
152 do gtx = lbound (ioi_data.gt, 1) to hbound (ioi_data.gt, 1);
153 gtep = addr (ioi_data.gt (gtx));
154 if gte.mplex & (gte.disk_data_subsystem_idx = 0) then do;
155 do ctep = ptr (idp, gte.ctep) repeat ptr (idp, cte.next_ctep) while (rel (ctep));
156 if ^cte.deleted then do;
157 call io_manager$assign (cte.chx, cte.chanid, ioi_masked$interrupt, bin (rel (ctep)),
158 statusp, code);
159 if code ^= 0 then
160 call syserr$error_code (CRASH, code, "^a: Unable to assign channel ^a.", ME,
161 cte.chanid);
162 cte.statusp = statusp;
163 cte.ioi_use = "1"b;
164 end;
165 end;
166 end;
167 end;
168
169
170
171 do itx = lbound (ioi_data.it, 1) to hbound (ioi_data.it, 1);
172 itep = addr (ioi_data.it (itx));
173 if ite.model = "imu" | ite.model = "iioc" then do;
174 call allocate_gte ("mca" || substr ("abcd", ite.tag, 1));
175 gte.psia = "1"b;
176 gte.n_devices = 1;
177 call allocate_ctes (ite.tag, 3, 1);
178 device_number = 1;
179 adding_controller_dte = "0"b;
180 call allocate_next_dte;
181 end;
182 end;
183
184
185
186 call ioi_page_table$init;
187
188
189
190 idcwp = addr (ioi_data.rss_idcw);
191 string (idcw) = ""b;
192 idcw.command = "40"b3;
193 idcw.code = "7"b3;
194 idcw.chan_cmd = "02"b3;
195 idcw.count = "01"b3;
196
197 ioi_data.setup = "1"b;
198 return;
199 %page;
200
201
202
203
204
205 allocate_gte:
206 proc (prph_name);
207
208
209 dcl current_gtx fixed bin;
210 dcl prph_name char (4) aligned;
211
212 do current_gtx = 1 to high_gtx;
213 gtep = addr (ioi_data.gt (current_gtx));
214 if gte.name = prph_name then
215 call syserr (CRASH, "^a: Duplicate ""prph ^a"" card found.", ME, gte.name);
216 end;
217 high_gtx = high_gtx + 1;
218 gtep = addr (ioi_data.gt (high_gtx));
219 gte.lock = ""b;
220 gte.name = prph_name;
221 gte.dtep, gte.ctep = ""b;
222 string (gte.flags) = ""b;
223 gte.n_devices = 0;
224 gte.pending_connects = 0;
225 gte.disk_data_subsystem_idx = 0;
226
227 end allocate_gte;
228
229
230
231
232 find_gte:
233 proc () returns (bit (1) aligned);
234
235 dcl current_gtx fixed bin;
236
237 do current_gtx = 1 to ioi_data.ngt;
238 gtep = addr (ioi_data.gt (current_gtx));
239 if chnl_card.name = gte.name then
240 return ("1"b);
241 end;
242 call syserr (CRASH, "^a: No matching ""prph ^a"" found for ""chnl ^a"".", ME, chnl_card.name, chnl_card.name);
243 return ("0"b);
244
245 end find_gte;
246 ^L
247
248
249 extended_status_command:
250 proc () returns (bit (6));
251
252 if gte.fips then
253 return ("00"b3);
254 else if device_type = "dsk" then
255 return ("22"b3);
256 else if device_type = "tap" then
257 return ("50"b3);
258 else if (device_type = "prt") | (device_type = "rdr") | (device_type = "pun") | (device_type = "ccu") then
259 return ("03"b3);
260 else return ("00"b3);
261
262 end extended_status_command;
263
264
265
266
267
268 ascii_detailed_status:
269 proc () returns (bit (1) aligned);
270
271 dcl i fixed bin;
272
273 if mpc_cardp ^= null () then
274 if substr (mpc_card.name, 1, 3) = "urp" then
275 do i = 1 to hbound (eurc_model_numbers, 1);
276 if mpc_card.model = eurc_model_numbers (i) then
277 return ("1"b);
278 end;
279 return ("0"b);
280
281 end ascii_detailed_status;
282 ^L
283
284
285
286
287
288 setup_log_status_info:
289 proc;
290
291 dcl log_status_info_idx fixed bin;
292
293 io_log_infop = addr (io_log_status_info$io_log_status_info);
294 do log_status_info_idx = 1 to io_log_info.ndev;
295 logp = addr (io_log_info.log_entry (log_status_info_idx));
296 if log.dev_name = device_type then do;
297 gte.io_log_info_index = log_status_info_idx;
298 return;
299 end;
300 end;
301 gte.io_log_info_index = 0;
302
303 end setup_log_status_info;
304 ^L
305
306
307 allocate_dtes_from_prph_card:
308 proc;
309
310 dcl group_idx fixed bin;
311
312 adding_controller_dte = "0"b;
313 if gte.fips then
314 device_number = 0;
315 else device_number = 1;
316 if (device_type = "tap") | (device_type = "dsk") then do;
317 NOTE
318 do group_idx = lbound (prph_tap_card_array.group, 1) to hbound (prph_tap_card_array.group, 1);
319 if prph_tap_card_array.group (group_idx).model ^= 0 then do;
320 do device_number = device_number
321 to device_number + prph_tap_card_array.group (group_idx).ndrives - 1;
322 call allocate_next_dte;
323 end;
324 end;
325 else device_number = device_number + prph_tap_card_array.group (group_idx).ndrives;
326 end;
327 adding_controller_dte = "1"b;
328 device_number = 0;
329 call allocate_next_dte;
330 end;
331 else call allocate_next_dte;
332 return;
333
334 end allocate_dtes_from_prph_card;
335 ^L
336 allocate_next_dte:
337 proc;
338
339 dcl device_name char (32);
340 dcl device_number_string pic "99";
341
342 if gte.mplex & ^(gte.fips & adding_controller_dte) then do;
343 device_number_string = device_number;
344 device_name = gte.name || "_" || device_number_string;
345 end;
346 else device_name = gte.name;
347 high_dtx = high_dtx + 1;
348 dtep = addr (ioi_data.dt (high_dtx));
349
350 unspec (dte) = ""b;
351 if gte.dtep = ""b then do;
352 gte.dtep = rel (dtep);
353 dte.next_dtep = rel (dtep);
354 end;
355 else do;
356 dte.next_dtep = ptr (dtep, gte.dtep) -> dte.next_dtep;
357
358 ptr (dtep, gte.dtep) -> dte.next_dtep = rel (dtep);
359 gte.dtep = rel (dtep);
360 end;
361 dte.gtep = rel (gtep);
362 dte.channel_required = "";
363 dte.workspace_ptr = null ();
364 dte.workspace_astep = null ();
365 dte.ptp = null ();
366 dte.in_use = "1"b;
367 dte.device = bit (bin (device_number, 6), 6);
368 dte.lock.event = unspec (IOI_DEVICE_LOCK_EVENT_TEMPLATE) || rel (dtep);
369
370 dte.device_table_idx = device_table_idx_from_name (device_name);
371 if dte.device_table_idx = 0 then
372 call syserr (CRASH, "^a: Couldn't find device_table_idx for device ""^a"".", ME, device_name);
373
374 dte.deleted = ^device_table.device_entry (dte.device_table_idx).configured;
375 if device_type = "fnp" | device_type = "dia" then
376 dte.direct = "1"b;
377 dte.controller = adding_controller_dte;
378
379
380 do dtep = ptr (idp, dte.next_dtep) repeat ptr (idp, dte.next_dtep) while (rel (dtep) ^= gte.dtep);
381 if bit (bin (device_number, 6), 6) = dte.device & ^adding_controller_dte then
382 call syserr (CRASH, "^a: Multiple definitions of device ^a found.", ME, device_name);
383 end;
384
385 end allocate_next_dte;
386 ^L
387
388
389 allocate_ctes_from_prph_card:
390 proc;
391
392 if device_type = "tap" | device_type = "dsk" then NOTE
393 call allocate_ctes (prph_dsk_card.iom, prph_dsk_card.chan, prph_dsk_card.nchan);
394 else call allocate_ctes (prph_card.iom, prph_card.chan, 1);
395
396 end allocate_ctes_from_prph_card;
397
398
399
400 allocate_ctes_from_chnl_card:
401 proc;
402
403 dcl group_idx fixed bin;
404
405 do group_idx = lbound (chnl_card_array.group, 1) to hbound (chnl_card_array.group, 1);
406 call allocate_ctes (chnl_card_array.group (group_idx).iom, chnl_card_array.group (group_idx).chan,
407 chnl_card_array.group (group_idx).nchan);
408 end;
409
410 end allocate_ctes_from_chnl_card;
411
412
413
414 allocate_ctes:
415 proc (iomno, channo, nchans);
416
417 dcl channo fixed bin (8) parameter;
418 dcl iomno fixed bin (3) parameter;
419 dcl nchans fixed bin parameter;
420
421 dcl ch_idx fixed bin;
422 dcl iterp bit (18);
423 dcl itx fixed bin;
424 dcl this_channel fixed bin (7);
425
426
427
428 do itx = 1 to high_itx while (ioi_data.it (itx).tag ^= iomno);
429 end;
430 if itx > high_itx then do;
431 call syserr (CRASH, "^a: No iom card found for the ^a subsystem.", ME, gte.name);
432 iterp = ""b;
433 end;
434 else iterp = rel (addr (ioi_data.it (itx)));
435
436
437
438
439
440
441 do ch_idx = nchans - 1 to 0 by -1;
442 high_ctx = high_ctx + 1;
443 ctep = addr (ioi_data.ct (high_ctx));
444 unspec (cte) = ""b;
445 cte.next_ctep = gte.ctep;
446 cte.itep = iterp;
447 gte.ctep = rel (ctep);
448 cte.gtep = rel (gtep);
449 this_channel = channo + ch_idx;
450 call io_chnl_util$iom_to_name (iomno, this_channel, cte.chanid, code);
451 if code ^= 0 then
452 call syserr$error_code (CRASH, code, "^a: Unable to get the name of IOM ^d channel ^d.", ME, iomno,
453 this_channel);
454 cte.channel_table_idx = channel_table_idx_from_name (cte.chanid);
455 cte.deleted = ^channel_table.channel_entry (cte.channel_table_idx).configured;
456 cte.direct = (device_type = "fnp") | (device_type = "dia");
457
458
459 do ctep = ptr (idp, cte.next_ctep) repeat ptr (idp, cte.next_ctep) while (rel (ctep));
460 if cte.chanid = ptr (idp, gte.ctep) -> cte.chanid then
461 call syserr (CRASH, "^a: Multiple definitions of channel ^a found for subsystem ^a.", ME,
462 cte.chanid, gte.name);
463 end;
464 end;
465
466 end allocate_ctes;
467
468 cte_offset:
469 proc (chanid) returns (bit (18));
470
471 dcl chanid char (8) aligned parameter;
472
473 dcl ctx fixed bin;
474
475 do ctx = lbound (ioi_data.ct, 1) to hbound (ioi_data.ct, 1);
476 if (addr (ioi_data.ct (ctx)) -> cte.chanid) = chanid then
477 return (rel (addr (ioi_data.ct (ctx))));
478 end;
479 return (""b);
480
481 end cte_offset;
482 ^L
483 iom_table_idx_from_tag:
484 proc (tag) returns (fixed bin);
485
486 dcl tag fixed bin (3) parameter;
487
488 dcl name char (1);
489 dcl i fixed bin;
490
491 name = substr ("ABCD", tag, 1);
492 do i = lbound (iom_table.iom_entry, 1) to hbound (iom_table.iom_entry, 1);
493 if iom_table.iom_entry (i).name = name then
494 return (i);
495 end;
496 return (lbound (iom_table.iom_entry, 1) - 1);
497
498 end iom_table_idx_from_tag;
499
500 device_table_idx_from_name:
501 proc (name) returns (fixed bin);
502
503 dcl name char (*) parameter;
504
505 dcl i fixed bin;
506
507 do i = lbound (device_table.device_entry, 1) to hbound (device_table.device_entry, 1);
508 if device_table.device_entry (i).name = name then
509 return (i);
510 end;
511 return (lbound (device_table.device_entry, 1) - 1);
512
513 end device_table_idx_from_name;
514
515 channel_table_idx_from_name:
516 proc (name) returns (fixed bin);
517
518 dcl name char (8) aligned parameter;
519
520 dcl i fixed bin;
521
522 do i = lbound (channel_table.channel_entry, 1) to hbound (channel_table.channel_entry, 1);
523 if channel_table.channel_entry (i).name = name then
524 return (i);
525 end;
526 return (lbound (channel_table.channel_entry, 1) - 1);
527
528 end channel_table_idx_from_name;
529
530
531
532 IS_ON_IMU:
533 proc (iomno) returns (bit (1));
534
535 dcl iomno fixed bin (3) parameter;
536 dcl itx fixed bin;
537
538
539
540 do itx = 1 to high_itx while (ioi_data.it (itx).tag ^= iomno);
541 end;
542 if itx > high_itx then
543 return ("0"b);
544 if ioi_data.it (itx).model = "imu" | ioi_data.it (itx).model = "iioc" then
545 return ("1"b);
546 else return ("0"b);
547 end IS_ON_IMU;
548 ^L
549
550
551
552
553 setup_disk_sharing:
554 proc;
555
556 dcl ctx fixed bin;
557
558 call find_disktab;
559 mpc_cardp = null ();
560 do ctx = lbound (null () -> disk_channel_table, 1) + disktab.nchan - 1
561 to lbound (null () -> disk_channel_table, 1) by -1;
562
563 cp = addr (ptr (diskp, disktab.channels) -> disk_channel_table (ctx));
564 if chantab.chanid ^= "" then do;
565 call find_matching_cte;
566 cte.statusp = chantab.statusp;
567 cte.chx = chantab.chx;
568 cte.disktab_ctx = ctx;
569 chantab.ioi_ctx = bin (rel (ctep));
570 if mpc_cardp = null () then
571 mpc_cardp = ioi_config$find_controller_card (cte.chanid);
572 else if mpc_cardp ^= ioi_config$find_controller_card (cte.chanid) then
573 gte.dual_controller = "1"b;
574 end;
575 end;
576
577 find_disktab:
578 proc;
579
580 dcl dtx fixed bin;
581
582 do dtx = lbound (disk_data.array, 1) to hbound (disk_data.array, 1);
583 if disk_data.array (dtx).name = gte.name then do;
584 gte.disk_data_subsystem_idx = dtx;
585 diskp = ptr (disksp, disk_data.array (dtx).offset);
586 return;
587 end;
588 end;
589 call syserr (CRASH, "^a: No entry for ^a found in disk_data.", ME, gte.name);
590
591 end find_disktab;
592
593 find_matching_cte:
594 proc;
595
596 do ctep = ptr (idp, gte.ctep) repeat ptr (idp, cte.next_ctep) while (rel (ctep));
597 if cte.chanid = chantab.chanid then
598 return;
599 end;
600 call syserr (CRASH, "^a: No cte found for channel ^a.", ME, chantab.chanid);
601
602 end find_matching_cte;
603
604 end setup_disk_sharing;
605 ^L
606 %include ioi_data;
607 %page;
608 %include io_config_data;
609 %page;
610 %include config_iom_card;
611 %page;
612 %include config_mpc_card;
613 %page;
614 %include config_ipc_card;
615 %page;
616 %include config_prph_card;
617 %page;
618 %include config_prph_tap_card;
619 %page;
620 %include config_prph_dsk_card;
621 %page;
622 %include config_chnl_card;
623 %page;
624 %include dskdcl;
625 %page;
626 %include io_chnl_util_dcls;
627 %page;
628 %include io_manager_dcls;
629 %page;
630 %include io_log_status_info;
631 %page;
632 %include iom_pcw;
633 %page;
634 %include eurc_model_numbers;
635 %page;
636 %include syserr_constants;
637 ^L
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740 end ioi_init;