1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 disk_init:
16 procedure (pvtx, confp);
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 dcl pvtx fixed bin parameter;
59 dcl confp ptr parameter;
60
61 dcl sx fixed bin;
62 dcl type fixed bin (8);
63 dcl name char (4) aligned;
64 dcl chx fixed bin (35);
65 dcl idx fixed bin (12);
66 dcl i fixed bin;
67 dcl j fixed bin;
68 dcl k fixed bin;
69 dcl ci fixed bin;
70 dcl devt fixed bin;
71 dcl dev_array (0:63) fixed bin;
72 dcl rcode fixed bin (35);
73 dcl base bit (24) aligned;
74 dcl fips_disk bit (1);
75 dcl chan_array (dskdcl_chans_per_subsys) char (8) aligned;
76
77
78
79
80 dcl adaptor_index fixed bin;
81 dcl adaptor_count fixed bin;
82
83 dcl 1 adaptor (4),
84 2 channel_start fixed bin,
85 2 chantab_index fixed bin,
86 2 channel_count fixed bin,
87 2 channels_used fixed bin;
88
89 dcl 1 d like devtab;
90
91
92
93 dcl response (0:6) float bin (27) static options (constant) initial (
94
95 100.0,
96 50000.0,
97 20.0,
98 50.0,
99 1.0,
100 200.0,
101 100000.0
102 );
103
104 dcl ME char (16) static options (constant) init ("disk_init");
105
106 dcl absadr ext entry (ptr, fixed bin (35)) returns (fixed bin (24));
107 dcl config_$find_2 entry (char (4), char (4) aligned, pointer);
108 dcl dctl$disk_inter entry (bit (36) aligned, fixed bin (3), bit (36) aligned);
109 dcl syserr ext entry options (variable);
110
111 dcl error_table_$io_not_configured
112 fixed bin (35) ext static;
113
114 dcl (addr, addrel, bin, bit, clock, currentsize, divide, float, hbound, mod, null, ptr, rel, size,
115 substr, unspec) builtin;
116 ^L
117 prph_dsk_cardp = confp;
118 disksp = addr (disk_seg$);
119
120 if disk_data.free_offset = "0"b then do;
121 disk_data.free_offset = bit (bin (currentsize (disk_data), 18));
122
123 statp = addr (disksp -> disk_data.status_mask);
124
125 status.power = "1"b;
126 status.major = "1111"b;
127 status.channel_stat = "111"b;
128 status.central_stat = "111"b;
129
130
131
132 unspec (disk_data.free_q) = "0"b;
133 do i = 1 to disk_data.free_q_size - 1;
134 disk_data.free_q_entries (i).next = rel (addr (disk_data.free_q_entries (i + 1)));
135 disk_data.free_q_entries (i + 1).prev = rel (addr (disk_data.free_q_entries (i)));
136 end;
137
138 disk_data.free_q.head = rel (addr (disk_data.free_q_entries (1)));
139
140 disk_data.free_q.tail = rel (addr (disk_data.free_q_entries (disk_data.free_q_size)));
141
142 disk_data.lock = ""b;
143
144
145
146 unspec (disk_data.sys_info) = "0"b;
147 disk_data.sys_info (PAGE_READ).max_depth = 6.0;
148 disk_data.sys_info (PAGE_READ).depth_map = rel (addr (disk_data.sys_info (PAGE_READ).depth));
149
150 disk_data.sys_info (PAGE_WRITE).max_depth = float (disk_data.free_q_size) * 0.75;
151 disk_data.sys_info (PAGE_WRITE).depth_map = rel (addr (disk_data.sys_info (PAGE_WRITE).depth));
152
153 disk_data.sys_info (VTOC_READ).max_depth = 6.0;
154 disk_data.sys_info (VTOC_READ).depth_map = rel (addr (disk_data.sys_info (VTOC_READ).depth));
155
156 disk_data.sys_info (VTOC_WRITE).max_depth = 12.0;
157 disk_data.sys_info (VTOC_WRITE).depth_map = rel (addr (disk_data.sys_info (VTOC_WRITE).depth));
158
159 disk_data.sys_info (BOOTLOAD_READ).max_depth = 6.0;
160 disk_data.sys_info (BOOTLOAD_READ).depth_map = rel (addr (disk_data.sys_info (BOOTLOAD_READ).depth));
161
162 disk_data.sys_info (BOOTLOAD_WRITE).max_depth = 12.0;
163 disk_data.sys_info (BOOTLOAD_WRITE).depth_map = rel (addr (disk_data.sys_info (BOOTLOAD_WRITE).depth));
164
165 disk_data.sys_info (TEST).max_depth = 1.0;
166 disk_data.sys_info (TEST).depth_map = rel (addr (disk_data.sys_info (TEST).depth));
167
168
169
170 disk_data.stagnate_time = 5000000;
171 disk_data.max_depth_reset_time = clock ();
172 end;
173 ^L
174
175
176 pvt_arrayp = addr (pvt$array);
177 pvtep = addr (pvt_array (pvtx));
178
179 type = pvte.device_type;
180 name = pvte.devname;
181
182 do sx = 1 to disk_data.subsystems while (name ^= disk_data.name (sx));
183 end;
184
185 pvtdip = addr (pvte.dim_info);
186 pvtdi.sx = sx;
187
188 pvtdi.usable_sect_per_cyl = divide (sect_per_cyl (type), sect_per_rec (type), 17, 0) * sect_per_rec (type);
189
190 pvtdi.unused_sect_per_cyl = sect_per_cyl (type) - pvtdi.usable_sect_per_cyl;
191
192
193 if sx > disk_data.subsystems then do;
194 disk_data.subsystems = sx;
195 disk_data.name (sx) = name;
196 disk_data.offset (sx) = disk_data.free_offset;
197
198
199 diskp = ptr (disksp, disk_data.free_offset);
200 call init_disk_database;
201
202 disk_data.free_offset = rel (addrel (diskp, currentsize (disktab) + disktab.nchan * size (chantab)));
203 end;
204
205 else
206 diskp = ptr (disksp, disk_data.offset (sx));
207
208 disktab.pvtx (pvte.logical_area_number) = pvtx;
209
210 return;
211 ^L
212 IS_FIPS:
213 procedure () returns (bit (1));
214 dcl groupx fixed bin;
215 dcl i fixed bin;
216
217 do groupx = 1 to hbound (prph_dsk_card.group, 1) while (prph_dsk_card.group (groupx).model ^= -1);
218 if prph_dsk_card.group (groupx).model ^= 0 then do;
219 do i = 1 to config_data_$disk_drive_model_names.count;
220 if config_data_$disk_drive_model_names.names (i).model = prph_dsk_card.group (groupx).model then
221 return (config_data_$disk_drive_model_names.names (i).device_0_valid);
222 end;
223 call syserr (CRASH, "^a: Disk model ^d not found in config_data_.", ME,
224 prph_dsk_card.group (groupx).model);
225 end;
226 end;
227 call syserr (CRASH, "^a: No valid disk models found on PRPH ^a card.", ME, prph_dsk_card.name);
228 end IS_FIPS;
229 ^L
230 init_disk_database:
231 procedure;
232
233 disktab.abs_mem_addr = absadr (addr (disktab), rcode);
234 if rcode ^= 0 then
235 goto absadr_error;
236
237
238
239 call check_config_fields (prph_dsk_cardp, addr (prph_dsk_card.group));
240
241 fips_disk = IS_FIPS ();
242 if fips_disk then
243 disktab.first_dev = 0;
244 else disktab.first_dev = 1;
245
246 j = disktab.first_dev;
247
248 do i = 1 to hbound (prph_dsk_card.group, 1) while (prph_dsk_card.group (i).model ^= -1);
249
250 call check_config_fields (prph_dsk_cardp, addr (prph_dsk_card.group (i).ndrives));
251
252 if (j + prph_dsk_card.group (i).ndrives - disktab.first_dev) > hbound (dev_array, 1) then
253
254 call syserr (CRASH, "^a: Too many devices configured for ^a. Max device is ^d.", ME, name,
255 hbound (dev_array, 1));
256 devt = prph_dsk_card.group (i).model;
257 if devt ^= 0 then do;
258 do devt = 1 to hbound (MODEL, 1) while (MODEL (devt) ^= prph_dsk_card.group (i).model);
259 end;
260 if devt > hbound (MODEL, 1) then
261 call syserr (CRASH, "^a: Unknown model number ^d on PRPH ^a", ME, prph_dsk_card.group (i).model,
262 name);
263 devt = MODELX (devt);
264 end;
265 do k = j to j + prph_dsk_card.group (i).ndrives - 1;
266 dev_array (k) = devt;
267 end;
268 j = j + prph_dsk_card.group (i).ndrives;
269 end;
270
271 disktab.last_dev, disktab.dev_index = j - 1;
272
273
274
275 unspec (d.opt_info) = "0"b;
276 do i = 0 to MAX_IO_TYPE;
277 sysp = addr (disk_data.sys_info (i));
278 d.opt_info (i).sys_info = rel (addr (sys_info.fraction));
279 if sys_info.max_depth > 1.0 then do;
280 d.opt_info (i).slope = (response (i) - 1.0) / (sys_info.max_depth - 1.0);
281 d.opt_info (i).intercept = ((response (i) * sys_info.max_depth) - 1.0) / (sys_info.max_depth - 1.0);
282 end;
283 else do;
284 d.opt_info (i).slope = 0.0;
285 d.opt_info (i).intercept = 1.0e10;
286 end;
287 end;
288
289
290
291 do i = disktab.first_dev to disktab.last_dev;
292 dp = addr (disktab.devtab (i));
293 if dev_array (i) > 0 then
294 if shared_spindle (dev_array (i)) then
295 if mod (i, 2) ^= 0 then do;
296 if i >= disktab.last_dev then do;
297
298 MISSING_BUDDY:
299 call syserr (CRASH, "^a: ^a ^[^d^s^;^s^d^] must be configured if ^a ^d is configured.",
300 ME, name, mod (i, 2) = 0, i - 1, i + 1, name, i);
301 end;
302 if dev_array (i + 1) ^= dev_array (i) then do;
303
304 BAD_BUDDY:
305 call syserr (CRASH, "^a: Devices ^d and ^d of ^a must have the same model number.", ME,
306 i - 1 + mod (i, 2), i + mod (i, 2), name);
307 end;
308 devtab.buddy = i + 1;
309 devtab.pdi = i;
310 end;
311 else do;
312 if i <= 1 then
313 goto MISSING_BUDDY;
314 if dev_array (i - 1) ^= dev_array (i) then
315 goto BAD_BUDDY;
316 devtab.buddy,
317 devtab.pdi = i - 1;
318 end;
319 else do;
320
321 devtab.buddy = 0;
322 devtab.pdi = i;
323 end;
324 else ;
325
326
327
328 unspec (devtab.opt_info) = unspec (d.opt_info);
329 unspec (devtab.wq) = "0"b;
330 end;
331 ^L
332
333
334 if prph_dsk_card.nchan > dskdcl_chans_per_subsys then
335 TOO_MANY_CHANNELS:
336 call syserr (CRASH, "^a: Too many channels configured for ^a. Limit is ^d.", ME, name,
337 dskdcl_chans_per_subsys);
338
339 do j = 1 to prph_dsk_card.nchan;
340 call io_chnl_util$iom_to_name ((prph_dsk_card.iom), (prph_dsk_card.chan + j - 1), chan_array (j), rcode);
341 if rcode ^= 0 then
342 call syserr (CRASH, "^a: Invalid channel on PRPH ^a card.", ME, prph_dsk_card.name);
343 end;
344
345
346
347 adaptor_index = 1;
348 adaptor (1).channel_start = 1;
349 adaptor (1).channel_count = prph_dsk_card.nchan;
350 adaptor (1).channels_used = 0;
351 adaptor (1).chantab_index = 1;
352
353 chnl_cardp = null ();
354 call config_$find_2 ("chnl", name, chnl_cardp);
355 if chnl_cardp ^= null () then
356 do i = 1 to 3 while (chnl_card.group (i).iom > 0);
357
358 call check_config_fields (chnl_cardp, addr (chnl_card.group (i).nchan));
359
360
361 adaptor_index = adaptor_index + 1;
362 adaptor (adaptor_index).channel_start = j;
363 adaptor (adaptor_index).channel_count = chnl_card.group (i).nchan;
364 adaptor (adaptor_index).channels_used = 0;
365 adaptor (adaptor_index).chantab_index = j; note
366
367 do k = 0 to chnl_card.group (i).nchan - 1;
368 if j > dskdcl_chans_per_subsys then
369 goto TOO_MANY_CHANNELS;
370 call io_chnl_util$iom_to_name ((chnl_card.group (i).iom), (chnl_card.group (i).chan + k),
371 chan_array (j), rcode);
372 if rcode ^= 0 then
373 call syserr (CRASH, "^a: Invalid channel on CHNL ^a card", ME, chnl_card.name);
374 j = j + 1;
375 end;
376 end;
377
378 disktab.nchan = j - 1;
379
380
381
382
383 disktab.channels = rel (addrel (diskp, currentsize (disktab)));
384 ^L
385
386
387 ci = 0;
388 adaptor_count = adaptor_index;
389 adaptor_index = 0;
390 do i = 1 to disktab.nchan;
391 re_scan_adaptor:
392 adaptor_index = mod (adaptor_index, adaptor_count) + 1;
393 if adaptor (adaptor_index).channel_count <= 0 then
394 goto re_scan_adaptor;
395 else do;
396 adaptor (adaptor_index).channel_count = adaptor (adaptor_index).channel_count - 1;
397 k = adaptor (adaptor_index).channel_start + adaptor (adaptor_index).channels_used;
398 adaptor (adaptor_index).channels_used = adaptor (adaptor_index).channels_used + 1;
399 ci = ci + 1;
400 idx = (sx * dskdcl_chans_per_subsys) + ci - 1;
401
402 cp = addr (ptr (disksp, disktab.channels) -> disk_channel_table (ci));
403
404 chantab.chanid = chan_array (k);
405
406 call io_manager$assign (chx, chan_array (k), dctl$disk_inter, (idx), chantab.statusp, rcode);
407 if rcode ^= 0 then
408 if rcode ^= error_table_$io_not_configured then
409 call syserr (CRASH, "^a: Unable to assign ^a for ^a.", ME, chan_array (k),
410 disk_data.name (sx));
411 else ;
412 else do;
413 chantab.chx = chx;
414 chantab.in_use = "1"b;
415 disktab.channels_online = disktab.channels_online + 1;
416 end;
417 ^L
418
419
420 base = bit (absadr (addr (cp -> chantab.select_data.limit), rcode));
421 if rcode ^= 0 then
422 absadr_error:
423 call syserr (CRASH, "^a: error ^w from absadr for ^a ^a", ME, rcode, disk_data.name (sx),
424 chan_array (k));
425
426 idcwp = addr (chantab.rstdcw);
427 idcw.command = "42"b3;
428 idcw.code = "111"b;
429 idcw.control = "10"b;
430 idcw.chan_cmd = "02"b3;
431 idcw.count = "01"b3;
432
433 idcwp = addr (chantab.scdcw);
434 idcw.command = seek_command (devt);
435 idcw.ext = substr (base, 1, 6);
436 idcw.code = "111"b;
437 idcw.ext_ctl = "1"b;
438 idcw.control = "10"b;
439
440 dcwp = addr (chantab.sddcw);
441 dcw.address = substr (base, 7);
442 dcw.tally = "0001"b3;
443
444 idcwp = addr (chantab.dcdcw);
445 idcw.code = "111"b;
446 idcw.ext_ctl = "1"b;
447
448 dcwp = addr (chantab.dddcw);
449
450 base = bit (absadr (addr (cp -> chantab.detailed_status), rcode));
451 if rcode ^= 0 then
452 go to absadr_error;
453
454 idcwp = addr (chantab.dscdcw);
455 idcw.command = "22"b3;
456 idcw.ext = substr (base, 1, 6);
457 idcw.code = "111"b;
458 idcw.ext_ctl = "1"b;
459
460 dcwp = addr (chantab.dsddcw);
461 dcw.address = substr (base, 7);
462 dcw.tally = "0004"b3;
463
464 idcwp = addr (chantab.rssdcw);
465 idcw.command = "00"b3;
466 idcw.ext = substr (base, 1, 6);
467 idcw.code = "111"b;
468 idcw.ext_ctl = "1"b;
469 end;
470 end;
471
472 return;
473
474
475 end init_disk_database;
476 ^L
477
478
479 check_config_fields:
480 proc (cardp, fieldp);
481
482 dcl cardp ptr;
483 dcl fieldp ptr;
484
485 dcl field_inx fixed bin;
486
487 field_inx = bin (rel (fieldp)) - bin (rel (cardp));
488 if field_inx > cardp -> config_card.type_word.n_fields then
489
490 call syserr (CRASH, "^a: Invalid format for ^a^[ ^a^;^1s^] card.", ME, cardp -> config_card.word,
491 (cardp -> config_card.type_word.field_type (1) = CONFIG_STRING_TYPE
492 | cardp -> config_card.type_word.field_type (1) = CONFIG_SINGLE_CHAR_TYPE), cardp -> chnl_card.name);
493
494 end check_config_fields;
495 ^L
496 %include config_chnl_card;
497 %page;
498 %include config_data_dcls;
499 %page;
500 %include config_deck;
501 %page;
502 %include config_prph_dsk_card;
503 %page;
504 %include dskdcl;
505 %page;
506 %include fs_dev_types;
507 %page;
508 %include io_chnl_util_dcls;
509 %page;
510 %include io_manager_dcls;
511 %page;
512 %include iom_dcw;
513 %page;
514 %include iom_pcw;
515 %page;
516 %include iom_stat;
517 %page;
518 %include pvte;
519 %page;
520 %include syserr_constants;
521 ^L
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
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 end disk_init;