1
2
3
4
5
6
7
8
9
10
11
12
13
14 dn355:
15 procedure;
16 return;
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
59
60 %page;
61 interrupt:
62 entry (x_dno, x_level, x_status);
63
64 dcl x_dno fixed bin (35);
65 dcl x_level fixed bin (3);
66 dcl x_status bit (36) aligned;
67
68 if tc_data$system_shutdown ^= 0
69 then return;
70 interrupt_entry = "1"b;
71
72 call setup;
73 level = x_level;
74 if datanet_info.trace
75 then do;
76 if level ^= 3 | ^fnp_info.running
77 then syserr_severity = just_tell;
78 else syserr_severity = log;
79 call syserr (syserr_severity,
80 "dn355: FNP ^a level ^d status ^w^[ running^]^[ bootloading^]^[ t_and_d_in_progress^]", fnp_name,
81 level, x_status, fnp_info.running, fnp_info.bootloading, fnp_info.t_and_d_in_progress);
82 end;
83 if level ^= 3 & level ^= 7
84 then do;
85 call syserr (beeper, "dn355: FNP ^a invalid interrupt level ^o", fnp_name, level);
86 if fnp_info.bootloading
87 then if level = 1
88 then call dn355_boot_interrupt$system_fault (dno);
89 return;
90 end;
91
92 if (^fnp_info.t_and_d_in_progress) & (^fnp_info.running) & (^fnp_info.bootloading)
93 then return;
94
95 if ^stac (addr (lcte.lock), pds$processid)
96 then do;
97
98 do while (^stac (addr (fnp_info.queue_lock), pds$processid));
99 end;
100
101 if level = 7
102 then fnp_info.level_7_pending = "1"b;
103 else fnp_info.level_3_pending = "1"b;
104
105 if stac (addr (lcte.lock), pds$processid)
106 then call process_int_queue ("0"b);
107
108 else if ^stacq (fnp_info.queue_lock, "0"b, pds$processid)
109 then call syserr (crash_system, "dn355: inconsistent queue lock");
110 end;
111
112 else do;
113 call process_int (level);
114
115 do while (^stac (addr (fnp_info.queue_lock), pds$processid));
116 end;
117
118 call process_int_queue ("0"b);
119 end;
120
121 return;
122
123 global_exit:
124 if interrupt_entry
125 then do;
126 if stacq (lcte.lock, "0"b, pds$processid)
127 then if lcte.notify_reqd
128 then do;
129 lcte.notify_reqd = "0"b;
130 call pxss$notify (tty_ev);
131 end;
132
133 lcte.locked_for_interrupt = "0"b;
134
135 end;
136 return;
137 ^L
138
139 send_wcd:
140 entry (a_fnpp, a_pcbp, opa, chrsa, data);
141
142 dcl a_fnpp ptr,
143 a_pcbp ptr,
144 opa fixed bin (8),
145 data bit (*),
146 chrsa fixed bin (8);
147
148 dcl tdata bit (8 * 36);
149 dcl data_len fixed bin (8);
150
151 pcbp = a_pcbp;
152 go to send_join;
153
154 send_global_wcd:
155 entry (a_fnpp, opa, chrsa, data);
156
157 pcbp = null ();
158
159 send_join:
160 interrupt_entry = "0"b;
161 fnpp = a_fnpp;
162 ttybp = addr (tty_buf$);
163 infop = addr (dn355_data$);
164 lctep = fnp_info.lcte_ptr;
165 operation = opa;
166 if ^fnp_info.running
167 then return;
168
169 no_response = "0"b;
170 dno = fnp_info.fnp_number;
171 mbxp = fnp_info.mbx_pt;
172 data_len = min (length (tdata), chrsa);
173 if data_len > 0
174 then tdata = substr (data, 1, data_len);
175 else tdata = "0"b;
176
177 i = index (used_string, "0"b);
178 if i = 0
179 then do;
180 call make_q_entry (operation, data_len, tdata);
181 fnp_info.mbx_unavailable = fnp_info.mbx_unavailable + 1;
182
183 end;
184
185 else do;
186 subp = addr (datanet_mbx.dn355_sub_mbxes (i - 1));
187
188 if pcbp ^= null ()
189 then do;
190 string (sub_mbx.line_number) = string (pcb.line_number);
191
192 devx = pcb.devx;
193 end;
194
195 else string (sub_mbx.line_number) = "0"b;
196
197 sub_mbx.op_code = operation;
198 sub_mbx.cmd_data_len = divide (data_len, 6, 17, 0);
199
200 if operation = accept_direct_output
201 then do;
202 if ^pcb.flags.dialed
203 then call throw_away_output;
204
205 else call process_send_output (i - 1, "0"b);
206 end;
207
208 else if operation = set_echnego_break_table
209 then do;
210 if pcb.flags.dialed
211 then call send_echo_table (i - 1, tdata);
212 end;
213
214 else do;
215 sub_mbx.io_cmd = wcd;
216 smbx_cmd_data_long = substr (tdata, 1, data_len);
217
218 call send_mbx (i - 1);
219 fnp_info.output_control_transactions = fnp_info.output_control_transactions + 1;
220 end;
221
222
223 if no_response
224 then call report_fnp_no_response;
225 end;
226
227
228 return;
229 ^L
230 process_interrupt_queue:
231 entry (x_dno);
232
233 interrupt_entry = "0"b;
234 call setup;
235 on cleanup call check_lock;
236 masked = "1"b;
237 call pmut$wire_and_mask (wire_arg, wire_ptr);
238
239 do while (^stac (addr (fnp_info.queue_lock), pds$processid));
240 end;
241 queue_locked = "1"b;
242
243 call process_int_queue ("1"b);
244 return;
245 ^L
246 setup:
247 proc;
248
249 ttybp = addr (tty_buf$);
250 dno = x_dno;
251 infop = addr (dn355_data$);
252
253 fnpp = addr (datanet_info.per_datanet (dno));
254 fnp_name = fnp_info.fnp_tag;
255 mbxp = fnp_info.mbx_pt;
256 lctep = fnp_info.lcte_ptr;
257
258 return;
259 end setup;
260 ^L
261 process_int_queue:
262 proc (caller_masked);
263
264
265
266 dcl caller_masked bit (1);
267
268 do while (dequeue (level));
269 fnp_info.processed_from_q = fnp_info.processed_from_q + 1;
270
271 if ^stacq (fnp_info.queue_lock, "0"b, pds$processid)
272 then call syserr (crash_system, "dn355: inconsistent queue lock");
273
274 queue_locked = "0"b;
275 if caller_masked
276 then call pmut$unwire_unmask (wire_arg, wire_ptr);
277 masked = "0"b;
278
279 call process_int (level);
280
281 if caller_masked
282 then do;
283 masked = "1"b;
284 call pmut$wire_and_mask (wire_arg, wire_ptr);
285 end;
286
287 do while (^stac (addr (fnp_info.queue_lock), pds$processid));
288 end;
289 queue_locked = "1"b;
290 end;
291
292 lcte.locked_for_interrupt = "0"b;
293 if ^stacq (lcte.lock, "0"b, pds$processid)
294 then call syserr (crash_system, "dn355: LCTE lock ^^= processid");
295
296 if ^stacq (fnp_info.queue_lock, "0"b, pds$processid)
297 then call syserr (crash_system, "dn355: inconsistent queue lock");
298
299 queue_locked = "0"b;
300 if caller_masked
301 then call pmut$unwire_unmask (wire_arg, wire_ptr);
302 masked = "0"b;
303
304 if lcte.notify_reqd
305 then do;
306 lcte.notify_reqd = "0"b;
307 call pxss$notify (tty_ev);
308 end;
309
310 return;
311
312 dequeue:
313 proc (a_level) returns (bit (1));
314
315 dcl a_level fixed bin;
316
317 if fnp_info.level_3_pending
318 then do;
319 fnp_info.level_3_pending = "0"b;
320 a_level = 3;
321 return ("1"b);
322 end;
323
324 else if fnp_info.level_7_pending
325 then do;
326 fnp_info.level_7_pending = "0"b;
327 a_level = 7;
328 return ("1"b);
329 end;
330
331 else return ("0"b);
332
333 end ;
334 end ;
335 ^L
336 process_int:
337 proc (a_level);
338
339
340
341 dcl a_level fixed bin;
342
343 level = a_level;
344
345 lcte.locked_for_interrupt = "1"b;
346 if level = 7
347 then do;
348
349 if fnp_info.t_and_d_in_progress
350 then do;
351 if fnp_info.t_and_d_lev_7_occurred
352 then return;
353 fnp_info.t_and_d_lev_7_occurred = "1"b;
354 t_and_d_join:
355 if fnp_info.t_and_d_notify_requested
356 then do;
357 call pxss$notify (tty_ev);
358 fnp_info.t_and_d_notify_requested = "0"b;
359 end;
360 unspec (auto_net_event_message) = "0"b;
361 auto_net_event_message.version = NET_EVENT_MESSAGE_VERSION_1;
362 auto_net_event_message.network_type = MCS_NETWORK_TYPE;
363 auto_net_event_message.handle = dno;
364 auto_net_event_message.type = level;
365 unspec (net_event_message_arg) = unspec (auto_net_event_message);
366 call pxss$unique_ring_0_wakeup (fnp_info.boot_process_id, fnp_info.boot_ev_chan,
367 net_event_message_arg, 0);
368 return;
369 end;
370
371
372
373 fault_type = datanet_mbx.crash_data.fault_code;
374 if fault_type > hbound (dn355_messages$fault_names, 1) | fault_type < 0
375 then fault_name = "unknown fault";
376 else fault_name = dn355_messages$fault_names (fault_type);
377
378 call syserr (beeper, "dn355: emergency interrupt from FNP ^a: ^a", fnp_info.fnp_tag, fault_name);
379
380 if datanet_mbx.crash_data.ic ^= 0
381 then call syserr (just_tell, "FNP instruction counter = ^6o", datanet_mbx.crash_data.ic);
382
383 if fault_type = iom_channel_fault
384 then call syserr (just_tell, "channel ^o, fault status = ^6o", datanet_mbx.crash_data.fault_word,
385 datanet_mbx.crash_data.iom_fault_status);
386
387 else if fault_type = illegal_opcode
388 then if dn355_word.opcode = die_code
389 then do;
390 modulep = addr (dn355_messages$per_module);
391 module_num = fixed (dn355_word.modnum, 4);
392 if module_num > 0 & module_num <= hbound (dn355_modules.list_offset, 1)
393 & dn355_word.crash_code > 0 & dn355_word.crash_code <= hbound (modulep -> message_offset, 1)
394 then do;
395 reasonp = ptr (modulep, dn355_modules.list_offset (module_num));
396 reasonp = ptr (reasonp, reasonp -> message_offset (dn355_word.crash_code));
397
398 call syserr (just_tell, "^a: ^a", dn355_modules.name (module_num), dn355_reason.msg);
399 end;
400 end;
401
402 call report_fnp_crash;
403 return;
404 end;
405
406
407
408 if fnp_info.bootloading
409 then do;
410 call dn355_boot_interrupt (dno);
411 return;
412 end;
413
414 if fnp_info.t_and_d_in_progress
415 then do;
416 if fnp_info.t_and_d_lev_3_occurred
417 then return;
418 fnp_info.t_and_d_lev_3_occurred = "1"b;
419 go to t_and_d_join;
420 end;
421
422 if ^fnp_info.running
423 then return;
424
425 no_response = "0"b;
426
427 if fnp_info.count > 0
428 then call process_q;
429 ^L
430
431
432 timw = ldac (addr (datanet_mbx.term_inpt_mpx_wd));
433
434 do i = 0 to 7;
435
436 if timwb (i) & ^no_response
437 then do;
438
439 subp = addr (datanet_mbx.dn355_sub_mbxes (i));
440
441 datanet_mbx.mbx_used_flags.used (i) = "0"b;
442
443 datanet_mbx.num_in_use = datanet_mbx.num_in_use - 1;
444 fnp_info.cumulative_mbx_in_use = fnp_info.cumulative_mbx_in_use + datanet_mbx.num_in_use;
445 fnp_info.mbx_in_use_updated = fnp_info.mbx_in_use_updated + 1;
446
447 if sub_mbx.io_cmd = wcd
448 then do;
449 if sub_mbx.op_code = dump_mem | sub_mbx.op_code = patch_mem
450 then do;
451 fnp_info.dump_patch_in_progress = "0"b;
452 call pxss$notify (FNP_DUMP_PATCH_EVENT);
453 end;
454
455 else if sub_mbx.op_code = report_meters
456 then do;
457 call get_line_number;
458 if devx = -1
459 then if fnp_info.get_meters_waiting
460
461 then do;
462 fnp_info.get_meters_waiting = "0"b;
463 call pxss$notify (FNP_METER_EVENT);
464 end;
465 else ;
466
467 else if pcb.get_meters_waiting
468 then do;
469 pcb.get_meters_waiting = "0"b;
470 call pxss$notify (FNP_METER_EVENT);
471 end;
472
473 else pcb.copied_meters_ready = "1"b;
474
475 end;
476 end;
477
478 else do;
479 call get_line_number;
480 if sub_mbx.io_cmd = wtx
481 then do;
482
483 pcb.output_mbx_pending = "0"b;
484 dcwlptr = addr (fnp_info.dcw_list_array_ptr -> dcw_list_array (i));
485 chain_head_ptr = ptr (ttybp, bin (dcw_list (1).dcw_ptr, 18) - (tty_buf.absorig + dataoff));
486 call tty_space_man$free_chain ((pcb.devx), OUTPUT, chain_head_ptr);
487
488
489 if sub_mbx.command_data (1) ^= "0"b
490
491 then call process_send_output (i, "1"b);
492
493 end;
494
495
496
497 else do;
498 call syserr (beeper, "dn355: unrecognized io command ^o from FNP ^a for line ^o",
499 sub_mbx.io_cmd, fnp_info.fnp_tag, bin (string (sub_mbx.line_number), 10));
500
501 call report_fnp_crash;
502 return;
503 end;
504 end;
505 end;
506 end;
507
508 do i = 8 to 11;
509 if timwb (i) & ^no_response
510 then do;
511 subp = addr (datanet_mbx.fnp_sub_mbxes (i - 8));
512 call get_line_number;
513
514 if sub_mbx.io_cmd = rcd
515 then do;
516
517 if (sub_mbx.op_code = accept_direct_input) | (sub_mbx.op_code = send_output)
518 | (sub_mbx.op_code = input_in_mailbox)
519 then do;
520 fnp_info.bleft_355 = fnp_sub_mbx.n_free_buffers - 4;
521
522
523 if fnp_info.bleft_355 < 0
524 then
525 fnp_info.bleft_355 = 0;
526
527
528 if fnp_info.free_size > 16000000000
529 then do;
530 fnp_info.free_size = 0;
531 fnp_info.free_count = 0;
532 end;
533
534 fnp_info.free_size = fnp_info.free_size + fnp_info.bleft_355;
535 fnp_info.free_count = fnp_info.free_count + 1;
536 end;
537
538 if sub_mbx.op_code = accept_direct_input | sub_mbx.op_code = input_in_mailbox
539 then fnp_info.input_data_transactions = fnp_info.input_data_transactions + 1;
540 else fnp_info.input_control_transactions = fnp_info.input_control_transactions + 1;
541
542 if sub_mbx.op_code = accept_new_terminal
543 then do;
544
545
546 pcb.line_type, dialup_info.line_type = bin (sub_mbx.command_data (1), 17);
547 if sub_mbx.command_data (2)
548 then pcb.baud_rate = baud_table (bin (sub_mbx.command_data (2), 17));
549
550 do j = 1 to n_sync_line_types while (sync_line_type (j) ^= pcb.line_type);
551 end;
552 pcb.sync_line = (j <= n_sync_line_types);
553
554 if ^pcb.sync_line
555 then bits_per_char = 10;
556 else bits_per_char = 8;
557
558 max_buf_chars =
559 divide (divide (pcb.baud_rate, bits_per_char, 17, 0), buf_per_second, 17, 0);
560 pcb.max_buf_size = min (16 * divide (max_buf_chars + 67, 64, 17, 0), 128);
561
562 if pcb.line_type = LINE_COLTS
563 then pcb.max_buf_size = 128;
564
565 dialup_info.baud_rate = pcb.baud_rate;
566 dialup_info.max_buf_size = pcb.max_buf_size;
567 dialup_info.buffer_pad = 0;
568 dialup_info.receive_mode_device = (dialup_info.line_type = LINE_ETX);
569 dialup_info.pad = "0"b;
570 pcb.dialed = "1"b;
571
572 sub_mbx.op_code = terminal_accepted;
573
574 sub_mbx.cmd_data_len = 3;
575 if ^pcb.high_speed
576 then addr (sub_mbx.command_data) -> unal_number = 2;
577
578 else addr (sub_mbx.command_data) -> unal_number = 4;
579
580 sub_mbx.io_cmd = wcd;
581 call return_mbx (i);
582 interrupt_info = unspec (dialup_info);
583 call channel_manager$interrupt (devx, DIALUP, interrupt_info);
584
585 end;
586
587
588 else if sub_mbx.op_code = disconnected_line
589 then do;
590 pcb.dialed = "0"b;
591 call throw_away_output;
592 call channel_manager$interrupt (devx, HANGUP, ""b);
593 call free_mbx (i);
594
595 end;
596
597 else if sub_mbx.op_code = wru_timeout
598 then do;
599 if pcb.dialed
600 then call channel_manager$interrupt (devx, WRU_TIMEOUT, ""b);
601 call free_mbx (i);
602 end;
603
604 else if sub_mbx.op_code = break_condition
605 then do;
606
607 if pcb.dialed
608 then do;
609 if pcb.hndlquit
610 then call throw_away_output;
611 call channel_manager$interrupt (devx, QUIT, ""b);
612 end;
613 call free_mbx (i);
614 end;
615
616
617 else if sub_mbx.op_code = send_output
618 then do;
619
620 call free_mbx (i);
621 if pcb.dialed
622 then call process_send_output (-1, "1"b);
623
624 end;
625
626
627 else if sub_mbx.op_code = accept_direct_input
628 then do;
629
630 if pcb.dialed
631 then call process_accept_input;
632
633 else do;
634 sub_mbx.io_cmd = wcd;
635 sub_mbx.op_code = disconnect_this_line;
636 call return_mbx (i);
637 end;
638 end;
639
640 else if sub_mbx.op_code = error_message
641 then do;
642 offset = bin (error_msg.data (1), 18);
643
644 if offset > 0 & offset <= hbound (dn355_messages$error_messages, 1)
645 then do;
646 offset = dn355_messages$error_messages (offset);
647
648 reasonp = addr (dn355_messages$error_messages);
649
650 reasonp = ptr (reasonp, offset);
651
652 reason_msg = dn355_reason.msg;
653 end;
654
655 else reason_msg = "unrecognized error ^o ^o ^o";
656
657 do ix = 1 to 3;
658 full_words (ix) = bin (error_msg.data (ix + 1), 18);
659 end;
660 call syserr (just_tell, "dn355: Message from FNP ^a: " || reason_msg, fnp_info.fnp_tag,
661 full_words);
662 call free_mbx (i);
663 end;
664
665 else if sub_mbx.op_code = input_in_mailbox
666 then do;
667 if pcb.dialed
668 then call process_input_in_mbx;
669 else do;
670 sub_mbx.io_cmd = wcd;
671 sub_mbx.op_code = disconnect_this_line;
672 call return_mbx (i);
673 end;
674 end;
675
676 else if sub_mbx.op_code >= first_acu_op_code & sub_mbx.op_code <= last_acu_op_code
677 then do;
678 interrupt_info = bit (bin (sub_mbx.op_code, 9));
679 call channel_manager$interrupt (devx, DIAL_STATUS, interrupt_info);
680 call free_mbx (i);
681 end;
682
683 else if sub_mbx.op_code = line_status
684 then do;
685 interrupt_info = substr (unspec (sub_mbx.command_data), 1, 72);
686 call channel_manager$interrupt (devx, LINE_STATUS, interrupt_info);
687 call free_mbx (i);
688 end;
689
690 else if sub_mbx.op_code = ack_echnego_init
691 then do;
692 call free_mbx (i);
693 call channel_manager$interrupt (devx, ACKNOWLEDGE_ECHNEGO_INIT, "0"b);
694 end;
695
696 else if sub_mbx.op_code = ack_echnego_stop
697 then do;
698 call free_mbx (i);
699 call channel_manager$interrupt (devx, ACKNOWLEDGE_ECHNEGO_STOP, "0"b);
700 end;
701
702 else if sub_mbx.op_code = line_masked
703 then do;
704 pcb.dialed, pcb.listen = "0"b;
705 call throw_away_output;
706 call syserr (just_tell,
707 "dn355: FNP masked channel ^a.h^d^[0^;^]^d for excessive interrupts", fnp_info.fnp_tag,
708 binary (sub_mbx.line_number.la_no, 3), (binary (sub_mbx.line_number.slot_no, 6) < 10),
709 binary (sub_mbx.line_number.slot_no, 6));
710 call channel_manager$interrupt (devx, MASKED, ""b);
711 call free_mbx (i);
712
713 end;
714
715 else do;
716 call syserr (beeper, "dn355: unrecognized op code ^o with rcd from FNP ^a for devx ^o",
717 sub_mbx.op_code, fnp_info.fnp_tag, devx);
718
719 call report_fnp_crash;
720 return;
721 end;
722 end;
723
724
725
726 else if sub_mbx.io_cmd = rtx
727 then call process_rtx;
728
729 else do;
730 call syserr (beeper, "dn355: unrecognized io command ^o from FNP ^a for line ^o", sub_mbx.io_cmd,
731 fnp_info.fnp_tag, bin (string (sub_mbx.line_number), 10));
732
733 call report_fnp_crash;
734 return;
735 end;
736 end;
737 end;
738
739
740 if ^no_response
741 then if fnp_info.count > 0
742 then call process_q;
743
744
745 if no_response
746 then call report_fnp_no_response;
747
748 return;
749 end ;
750 ^L
751 process_q:
752 proc;
753
754
755
756
757
758 q_first = fnp_info.cur_ptr;
759 q_count = fnp_info.count;
760 i = 1;
761
762 do while (q_count > 0 & i > 0);
763 i = index (used_string, "0"b);
764 if i > 0
765 then do;
766 subp = addr (datanet_mbx.dn355_sub_mbxes (i - 1));
767 qptr = ptr (ttybp, q_first);
768 if q_entry.pcb_offset ^= "0"b
769 then do;
770 pcbp = ptr (ttybp, q_entry.pcb_offset);
771 string (sub_mbx.line_number) = string (pcb.line_number);
772 devx = pcb.devx;
773 end;
774 else string (sub_mbx.line_number) = ""b;
775
776 if q_entry.opcode = accept_direct_output
777 then if pcb.dialed
778 then call process_send_output (i - 1, "0"b);
779 else ;
780
781 else if q_entry.opcode = set_echnego_break_table
782 then if pcb.dialed
783 then call send_echo_table (i - 1, q_entry.cmd_data);
784 else ;
785
786 else do;
787 sub_mbx.io_cmd = wcd;
788 sub_mbx.op_code = q_entry.opcode;
789 sub_mbx.cmd_data_len = divide (q_entry.cmd_count, 6, 8, 0);
790 smbx_cmd_data_long = substr (q_entry.cmd_data, 1, q_entry.cmd_count);
791 call send_mbx (i - 1);
792 fnp_info.output_control_transactions = fnp_info.output_control_transactions + 1;
793 end;
794
795 if no_response
796 then go to update_q_ptrs;
797
798 q_first = q_entry.next;
799 q_count = q_count - 1;
800 call tty_space_man$free_space (size (q_entry), qptr);
801 end;
802
803 else fnp_info.mbx_unavailable = fnp_info.mbx_unavailable + 1;
804 end;
805
806 update_q_ptrs:
807 fnp_info.cur_ptr = q_first;
808 fnp_info.count = q_count;
809 if q_count = 0
810 then fnp_info.last_ptr = 0;
811
812 return;
813 end ;
814 ^L
815
816
817 process_send_output:
818 proc (a_mbx_num, interrupt_entry);
819
820 dcl a_mbx_num fixed bin;
821 dcl mbx_num fixed bin;
822 dcl interrupt_entry bit (1) aligned;
823
824 mbx_num = a_mbx_num;
825 if pcb.end_frame | pcb.output_mbx_pending
826 then do;
827 pcb.flags.send_output = "1"b;
828 return;
829 end;
830
831 if pcb.write_first = 0
832 then do;
833 pcb.flags.send_output = "1"b;
834 call channel_manager$interrupt (devx, SEND_OUTPUT, ""b);
835 end;
836
837 else do;
838 if mbx_num = -1
839 then do;
840 mbx_num = index (used_string, "0"b) - 1;
841
842 if mbx_num = -1
843 then do;
844 call make_q_entry (accept_direct_output, 0, ""b);
845 fnp_info.mbx_unavailable = fnp_info.mbx_unavailable + 1;
846 return;
847 end;
848 else do;
849 subp = addr (datanet_mbx.dn355_sub_mbxes (mbx_num));
850 string (sub_mbx.line_number) = string (pcb.line_number);
851 end;
852 end;
853
854
855 pcb.flags.send_output = "0"b;
856 dcwlptr = addr (fnp_info.dcw_list_array_ptr -> dcw_list_array (mbx_num));
857
858 sub_mbx.data_addr = bit (bin (bin (rel (dcwlptr), 18) + tty_buf.absorig, 18), 18);
859 output_limit =
860 max (
861 min (divide ((fnp_info.bleft_355 - tc_data$fnp_buffer_threshold) * 60, output_bpart, 17, 0),
862 max_chain_len * 4 * (pcb.max_buf_size - 1)), 1);
863
864 output_chars = 0;
865 continue = "1"b;
866 do j = 1 to max_chain_len while (pcb.write_first ^= 0 & output_chars < output_limit & continue);
867
868 dcw_list (j).dcw_ptr = bit (bin (pcb.write_first + dataoff + tty_buf.absorig, 18), 18);
869
870 blockp = ptr (ttybp, pcb.write_first);
871 if buffer.tally = 0
872 then call syserr (crash_system, "dn355: output buffer at ^o has zero tally", pcb.write_first);
873
874 dcw_list (j).dcw_tally = bit (buffer.tally, 9);
875
876 dcw_list (j).pad = "0"b;
877 pcb.write_first = buffer.next;
878 pcb.write_cnt = pcb.write_cnt - buffer.tally;
879
880 output_chars = output_chars + buffer.tally;
881
882 if buffer.flags.end_of_page
883 then do;
884 pcb.flags.end_frame = "1"b;
885 continue = "0"b;
886 end;
887 end;
888
889 chain_len = max (j - 1, 1);
890
891 sub_mbx.word_cnt = chain_len;
892 sub_mbx.op_code = accept_direct_output;
893 sub_mbx.command_data (1) = "0"b;
894 sub_mbx.io_cmd = wtx;
895 pcb.output_mbx_pending = "1"b;
896 buffer.next = 0;
897 call send_mbx (mbx_num);
898 fnp_info.output_data_transactions = fnp_info.output_data_transactions + 1;
899 lcte.meters.out_bytes = lcte.meters.out_bytes + output_chars;
900
901
902 if pcb.write_first = 0
903 then do;
904 pcb.write_last = 0;
905 if interrupt_entry
906 then call channel_manager$interrupt (devx, SEND_OUTPUT, ""b);
907
908 end;
909 else if chain_len < max_chain_len & ^pcb.flags.end_frame
910
911 then fnp_info.fnp_space_restricted_output = fnp_info.fnp_space_restricted_output + 1;
912 end;
913
914 return;
915 end;
916 ^L
917
918
919
920
921
922
923
924 send_echo_table:
925 procedure (mbx_num, table_bits);
926
927 dcl mbx_num fixed bin;
928 dcl table_bits bit (8 * 36);
929
930 dcl table_ptr pointer;
931 dcl bits_to_send bit (8 * 36) based;
932
933 if ^pcb.dialed
934 then return;
935 table_ptr = addr (fnp_info.dcw_list_array_ptr -> dcw_list_array (mbx_num));
936 table_ptr -> bits_to_send = table_bits;
937 sub_mbx.op_code = set_echnego_break_table;
938 sub_mbx.io_cmd = wcd;
939 sub_mbx.data_addr = bit (bin (bin (rel (table_ptr), 18) + tty_buf.absorig, 18), 18);
940 sub_mbx.word_cnt = 8;
941
942 call send_mbx (mbx_num);
943 fnp_info.output_control_transactions = fnp_info.output_control_transactions + 1;
944 return;
945 end send_echo_table;
946 ^L
947
948
949 process_accept_input:
950 proc;
951
952 dcl tally fixed bin;
953 dcl buf_size fixed bin;
954 dcl prev_blockp ptr;
955
956 input_count = input_sub_mbx.n_chars;
957 j = divide (input_count + 3, 4, 17, 0);
958
959 if enough_input_space (j) & pcb.read_first = 0
960 then do;
961 do k = 1 to input_sub_mbx.n_buffers;
962 tally = input_sub_mbx.dcw (k).tally;
963 buf_size = 16 * divide (tally + 67, 64, 17, 0);
964
965 call tty_space_man$get_buffer (devx, buf_size, INPUT, blockp);
966 if blockp = null ()
967 then do;
968 if pcb.read_first ^= 0
969 then call tty_space_man$free_chain (devx, INPUT, ptr (ttybp, pcb.read_first));
970 pcb.read_first = 0;
971 go to reject;
972 end;
973
974 if pcb.read_first = 0
975 then pcb.read_first = bin (rel (blockp));
976 else prev_blockp -> buffer.next = bin (rel (blockp));
977
978 buffer.tally = tally;
979 input_sub_mbx.dcw (k).abs_addr =
980 bit (bin (tty_buf.absorig + bin (rel (addr (buffer.chars))), 24), 24);
981
982 prev_blockp = blockp;
983 end;
984
985 pcb.read_last = bin (rel (blockp));
986
987 sub_mbx.op_code = input_accepted;
988 sub_mbx.io_cmd = rtx;
989 call return_mbx (i);
990 end;
991
992 else do;
993 reject:
994 sub_mbx.io_cmd = wcd;
995 sub_mbx.op_code = reject_request_temp;
996
997 call return_mbx (i);
998 fnp_info.input_reject_count = fnp_info.input_reject_count + 1;
999 call channel_manager$interrupt (devx, INPUT_REJECTED, ""b);
1000 end;
1001
1002 end ;
1003 ^L
1004
1005 process_rtx:
1006 proc;
1007
1008 dcl real_word_cnt fixed bin;
1009 dcl n_words fixed bin;
1010 dcl buf_size fixed bin;
1011 dcl source_ptr ptr;
1012 dcl target_ptr ptr;
1013
1014 fnp_info.input_data_transactions = fnp_info.input_data_transactions + 1;
1015 real_word_cnt = input_sub_mbx.n_chars;
1016 lcte.meters.in_bytes = lcte.meters.in_bytes + real_word_cnt;
1017 rtx_info.break_char = substr (input_sub_mbx.command_data, 18, 1);
1018 call check_ff ("0"b);
1019 input_count = real_word_cnt;
1020 if input_count ^= 0
1021 then do;
1022 rtx_info.output_in_fnp = substr (input_sub_mbx.command_data, 17, 1);
1023 rtx_info.output_in_ring_0 = (pcb.write_first ^= 0);
1024 rtx_info.input_count = input_count;
1025 rtx_info.chain_head = bit (pcb.read_first, 18);
1026 rtx_info.chain_tail = bit (pcb.read_last, 18);
1027 interrupt_info = unspec (rtx_info);
1028 call channel_manager$interrupt (devx, ACCEPT_INPUT, interrupt_info);
1029 end;
1030
1031 else call tty_space_man$free_chain (devx, INPUT, ptr (ttybp, pcb.read_first));
1032
1033 pcb.read_first, pcb.read_last = 0;
1034
1035 call free_mbx (i);
1036
1037 return;
1038 ^L
1039 process_input_in_mbx:
1040 entry;
1041
1042
1043
1044 numchars = fnp_sub_mbx.n_chars;
1045 rtx_info.break_char = substr (fnp_sub_mbx.command_data, 18, 1);
1046 call check_ff ("1"b);
1047 if numchars > 0
1048 then do;
1049 n_words = divide (numchars + 3, 4, 17, 0);
1050 if enough_input_space (n_words)
1051 then do;
1052 buf_size = 16 * (divide (n_words + 17, 16, 17, 0));
1053
1054 call tty_space_man$get_buffer (devx, buf_size, INPUT, blockp);
1055 if blockp = null
1056 then go to not_enough_space;
1057
1058 source_ptr = addr (fnp_sub_mbx.input_data);
1059 target_ptr = addr (buffer.chars);
1060 target_ptr -> chars = source_ptr -> chars;
1061 buffer.tally = numchars;
1062 rtx_info.output_in_fnp = substr (fnp_sub_mbx.command_data, 17, 1);
1063 rtx_info.output_in_ring_0 = (pcb.write_first ^= 0);
1064 rtx_info.input_count = numchars;
1065 rtx_info.chain_head, rtx_info.chain_tail = rel (blockp);
1066
1067 lcte.meters.in_bytes = lcte.meters.in_bytes + numchars;
1068 interrupt_info = unspec (rtx_info);
1069 call channel_manager$interrupt (devx, ACCEPT_INPUT, interrupt_info);
1070 call free_mbx (i);
1071 end;
1072
1073 else do;
1074 not_enough_space:
1075 sub_mbx.io_cmd = wcd;
1076 sub_mbx.op_code = reject_request_temp;
1077 call return_mbx (i);
1078 call channel_manager$interrupt (devx, INPUT_REJECTED, ""b);
1079 end;
1080 end;
1081
1082 else call free_mbx (i);
1083 return;
1084 ^L
1085 check_ff:
1086 proc (in_mbx);
1087
1088 dcl in_mbx bit (1);
1089
1090 rtx_info.formfeed_present = "0"b;
1091 if pcb.sync_line
1092 then return;
1093
1094 if in_mbx
1095 then do;
1096 bufp = addr (fnp_sub_mbx.input_data);
1097 chars_left = numchars;
1098 end;
1099
1100 else do;
1101 blockp = ptr (ttybp, pcb.read_last);
1102 chars_left = buffer.tally;
1103 bufp = addr (buffer.chars);
1104 end;
1105
1106 if substr (bufp -> input_chars, chars_left, 1) = form_feed
1107
1108 then rtx_info.formfeed_present = "1"b;
1109 if pcb.flags.end_frame & rtx_info.break_char
1110 then do;
1111 if (chars_left <= 2)
1112 then if verify (substr (bufp -> input_chars, 1, chars_left), ff_cr_lf) = 0
1113 then do;
1114 if in_mbx
1115 then numchars = 0;
1116 else real_word_cnt = 0;
1117 end;
1118 pcb.flags.end_frame = "0"b;
1119 if pcb.flags.send_output
1120 then if pcb.write_first ^= 0
1121 then call make_q_entry (accept_direct_output, 0, ""b);
1122
1123 else call channel_manager$interrupt (devx, SEND_OUTPUT, ""b);
1124 end;
1125
1126 end ;
1127
1128 end ;
1129 ^L
1130
1131
1132 enough_input_space:
1133 proc (count) returns (bit (1));
1134
1135 dcl count fixed bin;
1136
1137 lctp = tty_buf.lct_ptr;
1138 chan_lctep = addr (lct.lcte_array (devx));
1139 return (chan_lctep -> lcte.input_words + count <= divide (tty_buf.bleft, input_bpart, 17, 0));
1140 end ;
1141 ^L
1142
1143
1144
1145 make_q_entry:
1146 proc (opc, cnt, databits);
1147
1148 dcl (opc, cnt) fixed bin (8),
1149 databits bit (8 * 36);
1150
1151 call tty_space_man$get_space (size (q_entry), new_qp);
1152 if new_qp = null
1153 then do;
1154 call syserr (crash_system, "dn355: unable to allocate block for delay queue");
1155 return;
1156 end;
1157
1158 new_qrel = bin (rel (new_qp));
1159 if fnp_info.cur_ptr = 0
1160 then fnp_info.cur_ptr = new_qrel;
1161 else do;
1162 qptr = ptr (ttybp, fnp_info.last_ptr);
1163 q_entry.next = new_qrel;
1164 end;
1165
1166 fnp_info.last_ptr = new_qrel;
1167 qptr = new_qp;
1168 fnp_info.count = fnp_info.count + 1;
1169 fnp_info.q_entries_made = fnp_info.q_entries_made + 1;
1170
1171 q_entry.opcode = opc;
1172 q_entry.cmd_count = cnt;
1173 if pcbp ^= null ()
1174 then q_entry.pcb_offset = rel (pcbp);
1175 else q_entry.pcb_offset = "0"b;
1176 q_entry.next = 0;
1177 q_entry.cmd_data = databits;
1178 return;
1179 end;
1180 ^L
1181
1182
1183 get_line_number:
1184 proc;
1185
1186 dcl x fixed bin;
1187
1188 if string (sub_mbx.line_number) = "0"b
1189 then do;
1190 do x = 1 to hbound (global_opcodes, 1) while (sub_mbx.op_code ^= global_opcodes (x));
1191 end;
1192 if x > hbound (global_opcodes, 1)
1193 then do;
1194 call syserr (beeper, "dn355: line number of 0 with non-global opcode in submbx ^o, FNP ^a", i,
1195 fnp_info.fnp_tag);
1196 call report_fnp_crash;
1197 go to global_exit;
1198 end;
1199
1200 pcbp = null;
1201 devx = -1;
1202 end;
1203
1204 else do;
1205 n_pcbs = fnp_info.no_of_channels;
1206 if string (sub_mbx.line_number) = TANDD_LINE_NUMBER
1207
1208 then pcbp = addr (fnp_info.pcb_array_ptr -> pcb_array (fnp_info.tandd_pcbx));
1209 else do;
1210 lano = sub_mbx.line_number.la_no;
1211 if sub_mbx.is_hsla
1212 then j = fnp_info.hsla_idx (fixed (lano));
1213 else j = fnp_info.lsla_idx (fixed (lano));
1214
1215 do j = j to n_pcbs;
1216 pcbp = addr (fnp_info.pcb_array_ptr -> pcb_array (j));
1217 if string (pcb.line_number) = string (sub_mbx.line_number)
1218 then go to match;
1219 end;
1220 call syserr (beeper, "dn355: no slot number match for sub mbx ^o, FNP ^a", i, fnp_info.fnp_tag);
1221
1222 call report_fnp_crash;
1223 go to global_exit;
1224 end;
1225
1226 match:
1227 devx = pcb.devx;
1228
1229 end;
1230 return;
1231
1232 end ;
1233 ^L
1234
1235
1236 send_mbx:
1237 return_mbx:
1238 proc (a_mbx_no);
1239
1240 dcl a_mbx_no fixed bin;
1241 dcl mbx_no fixed bin;
1242 dcl pcw_error bit (1);
1243 dcl timeout_time fixed bin (71);
1244 dcl 1 ima aligned like io_manager_arg;
1245
1246 mbx_no = a_mbx_no;
1247 go to test_pcw;
1248
1249 free_mbx:
1250 entry (a_mbx_no);
1251
1252 mbx_no = a_mbx_no + 4;
1253
1254 test_pcw:
1255 if ^fnp_info.io_manager_assigned
1256 then do;
1257 no_response = "1"b;
1258 return;
1259 end;
1260
1261 no_response = "0"b;
1262 if datanet_mbx.dia_pcw.command ^= "0"b
1263 then do;
1264 wait_for_response:
1265 timeout_time = clock () + TWO_SECONDS;
1266 do while ((clock () < timeout_time) & (datanet_mbx.dia_pcw.command ^= "0"b));
1267
1268 end;
1269 if datanet_mbx.dia_pcw.error | datanet_mbx.dia_pcw.command ^= "0"b
1270 then do;
1271 if ^no_response
1272 then do;
1273 pcw_error = datanet_mbx.dia_pcw.error;
1274 no_response = "1"b;
1275 datanet_mbx.dia_pcw.error = "0"b;
1276 string (datanet_mbx.dia_pcw) = dn355_util$compute_parity (string (datanet_mbx.dia_pcw));
1277
1278 ima.chx = fnp_info.io_manager_chx;
1279 ima.ptp = fnp_info.ptp;
1280 call io_manager$connect_direct (ima);
1281
1282 call syserr (just_tell,
1283 "dn355: ^[Error^;Timeout^] sending mailbox interrupt to FNP ^a, will retry.", pcw_error,
1284 fnp_info.fnp_tag);
1285 goto wait_for_response;
1286 end;
1287 end;
1288 else goto send_new_connect;
1289 end;
1290 else do;
1291 send_new_connect:
1292 no_response = "0"b;
1293
1294 if mbx_no < 8
1295 then do;
1296 datanet_mbx.mbx_used_flags.used (mbx_no) = "1"b;
1297 datanet_mbx.num_in_use = datanet_mbx.num_in_use + 1;
1298 fnp_info.max_mbx_in_use = max (fnp_info.max_mbx_in_use, datanet_mbx.num_in_use);
1299 fnp_info.cumulative_mbx_in_use = fnp_info.cumulative_mbx_in_use + datanet_mbx.num_in_use;
1300 fnp_info.mbx_in_use_updated = fnp_info.mbx_in_use_updated + 1;
1301 end;
1302 string (datanet_mbx.dia_pcw) = initial_pcw;
1303 datanet_mbx.dia_pcw.mbx_no = bit (fixed (mbx_no, 6), 6);
1304
1305
1306 string (datanet_mbx.dia_pcw) = dn355_util$compute_parity (string (datanet_mbx.dia_pcw));
1307
1308
1309 ima.chx = fnp_info.io_manager_chx;
1310 ima.ptp = fnp_info.ptp;
1311 call io_manager$connect_direct (ima);
1312
1313 return;
1314 end;
1315 end send_mbx;
1316 ^L
1317
1318
1319 hangup_fnp_lines:
1320 entry (a_fnp_no);
1321
1322 dcl a_fnp_no fixed bin;
1323
1324 ttybp = addr (tty_buf$);
1325 infop = addr (dn355_data$);
1326 call hangup_fnp (a_fnp_no);
1327 return;
1328
1329
1330 hangup_fnp:
1331 proc (fnp_no);
1332
1333 dcl fnp_no fixed bin;
1334
1335 fnpp = addr (datanet_info.per_datanet (fnp_no));
1336 n_pcbs = fnp_info.no_of_channels;
1337 do j = 1 to n_pcbs;
1338 pcbp = addr (fnp_info.pcb_array_ptr -> pcb_array (j));
1339 if pcb.dialed
1340 then do;
1341 call throw_away_output;
1342 call channel_manager$interrupt ((pcb.devx), CRASH, ""b);
1343 end;
1344 end;
1345
1346 if fnp_info.count > 0
1347 then do;
1348 q_count = fnp_info.count;
1349 q_first = fnp_info.cur_ptr;
1350 do q_count = q_count to 0 by -1 while (q_first ^= 0);
1351 qptr = ptr (ttybp, q_first);
1352 q_first = qptr -> q_entry.next;
1353 call tty_space_man$free_space (size (q_entry), qptr);
1354 end;
1355
1356 fnp_info.count, fnp_info.cur_ptr, fnp_info.last_ptr = 0;
1357 end;
1358
1359 end;
1360
1361
1362
1363 throw_away_output:
1364 proc;
1365
1366
1367
1368 if pcb.write_first ^= 0
1369 then do;
1370 call tty_space_man$free_chain ((pcb.devx), OUTPUT, ptr (ttybp, pcb.write_first));
1371 pcb.write_first, pcb.write_last, pcb.write_cnt = 0;
1372
1373 end;
1374
1375 pcb.end_frame = "0"b;
1376
1377 return;
1378 end ;
1379 ^L
1380
1381
1382 report_fnp_no_response:
1383 proc;
1384
1385 call syserr (beeper, "dn355: FNP ^a did not respond to mailbox interrupt", fnp_info.fnp_tag);
1386 call report_fnp_crash;
1387 return;
1388
1389 end ;
1390
1391
1392
1393
1394 report_fnp_crash:
1395 proc;
1396
1397 fnp_info.running = "0"b;
1398 if fnp_info.dump_patch_in_progress
1399 then call pxss$notify (FNP_DUMP_PATCH_EVENT);
1400
1401 if ^fnp_info.bootloading
1402 then
1403 call hangup_fnp (dno);
1404 else fnp_info.bootloading = "0"b;
1405
1406 auto_fnp_msg.state = FNP_DOWN;
1407 auto_fnp_msg.fnp_no = dno;
1408 auto_fnp_msg.flags = "0"b;
1409 unspec (fnp_event_message) = unspec (auto_fnp_msg);
1410 call pxss$ring_0_wakeup (fnp_info.boot_process_id, fnp_info.boot_ev_chan, fnp_event_message, 0);
1411
1412 return;
1413
1414 end report_fnp_crash;
1415 check_lock:
1416 proc;
1417
1418
1419
1420 if queue_locked
1421 then call syserr (crash_system, "dn355: attempted crawlout with FNP queue locked");
1422
1423 else if masked
1424 then call pmut$unwire_unmask (wire_arg, wire_ptr);
1425
1426 return;
1427 end check_lock;
1428 %page;
1429
1430
1431 dcl (dcwlptr, bufp, qptr) ptr,
1432 timw fixed bin (24),
1433 (level, dno, i, ix, q_first, q_count, chars_left, numchars, k, j, chain_len) fixed bin,
1434
1435 devx fixed bin,
1436 operation fixed bin (8),
1437 lano bit (3) unal;
1438 dcl fnp_name char (1) aligned;
1439
1440 dcl no_response bit (1) aligned;
1441
1442 dcl interrupt_entry bit (1);
1443
1444 dcl input_count fixed bin;
1445
1446 dcl chan_lctep ptr;
1447 dcl chain_head_ptr ptr;
1448 dcl output_limit fixed bin;
1449 dcl output_chars fixed bin;
1450
1451 dcl bits_per_char fixed bin;
1452 dcl max_buf_chars fixed bin;
1453
1454 dcl wire_arg fixed bin (71);
1455 dcl wire_ptr ptr;
1456 dcl masked bit (1);
1457 dcl queue_locked bit (1);
1458 dcl continue bit (1);
1459
1460 dcl offset fixed bin;
1461 dcl syserr_severity fixed bin (35);
1462
1463
1464
1465
1466
1467 dcl (
1468 dataoff init (1),
1469 max_chain_len init (16),
1470 just_tell init (0),
1471 beeper init (3),
1472 log init (4),
1473 crash_system init (1)
1474 ) fixed bin int static options (constant);
1475
1476 dcl FNP_DOWN fixed bin int static options (constant) init (2);
1477
1478 dcl initial_pcw bit (36) int static init ("000000000000000000000000000000111001"b);
1479
1480 dcl TANDD_LINE_NUMBER bit (10) int static options (constant) init ((10)"1"b);
1481
1482 dcl TWO_SECONDS fixed bin (71) int static options (constant) init (2000000);
1483
1484
1485 dcl timwb (0:11) bit (1) based (addr (timw)),
1486 used_string bit (8) based (addr (datanet_mbx.mbx_used_flags.used (0)));
1487
1488
1489 dcl (addr, binary, substr, stac, stacq, string, ptr, rel, index, fixed, divide, bin, max, min, null, length, bit, unspec,
1490 hbound, size, verify, clock) builtin;
1491
1492 dcl unal_number fixed bin (17) unal based,
1493 chars char (numchars) based;
1494
1495 dcl input_chars char (chars_left) based;
1496
1497 dcl smbx_cmd_data_long bit (216) unaligned based (addr (sub_mbx.command_data));
1498
1499 dcl tc_data$system_shutdown ext fixed bin;
1500 dcl tc_data$fnp_buffer_threshold ext static fixed bin;
1501 dcl pds$processid bit (36) aligned ext static;
1502
1503 dcl ff_cr_lf char (3) int static options (constant) init ("^L^M
1504 ");
1505
1506 dcl form_feed init ("^L") char (1) int static options (constant);
1507
1508 dcl syserr entry options (variable),
1509 ldac entry (ptr) returns (fixed bin (24)),
1510 dn355_util$compute_parity entry (bit (36)) returns (bit (36)),
1511 (
1512 dn355_boot_interrupt,
1513 dn355_boot_interrupt$system_fault
1514 ) entry (fixed bin),
1515 pxss$ring_0_wakeup entry (bit (36) aligned, fixed bin (71), fixed bin (71), fixed bin (35)),
1516 pxss$unique_ring_0_wakeup entry (bit (36) aligned, fixed bin (71), fixed bin (71), fixed bin (35)),
1517 pxss$notify entry (fixed bin);
1518
1519 dcl pmut$wire_and_mask entry (fixed bin (71), ptr);
1520 dcl pmut$unwire_unmask entry (fixed bin (71), ptr);
1521 dcl 1 auto_net_event_message aligned like net_event_message;
1522 dcl 1 auto_fnp_msg aligned like fnp_msg;
1523 dcl fnp_event_message fixed bin (71);
1524
1525 dcl 1 dcw_list (max_chain_len) aligned based (dcwlptr),
1526 2 dcw_ptr bit (18) unal,
1527 2 pad bit (9) unal,
1528 2 dcw_tally bit (9) unal;
1529
1530 dcl 1 dcw_list_array (0:7) aligned based,
1531 2 dcw_list_template (max_chain_len) like dcw_list;
1532
1533 dcl 1 q_entry aligned like fnp_queue_entry based (qptr);
1534
1535 dcl new_qp ptr;
1536 dcl new_qrel fixed bin;
1537
1538 dcl 1 dn355_word unal based (addr (datanet_mbx.fault_word)),
1539
1540 2 modnum bit (4),
1541 2 opcode fixed bin (4),
1542 2 crash_code fixed bin (8);
1543
1544 dcl fault_type fixed bin;
1545 dcl fault_name char (16);
1546 dcl module_num fixed bin;
1547
1548 dcl iom_channel_fault fixed bin int static init (9);
1549 dcl illegal_opcode fixed bin int static init (3);
1550 dcl die_code fixed bin int static init (9);
1551
1552 dcl 1 error_msg aligned based (addr (sub_mbx.command_data (1))),
1553
1554 2 data (4) bit (18) unal;
1555
1556 dcl full_words (3) fixed bin;
1557
1558 dcl reason_msg char (64);
1559
1560 dcl cleanup condition;
1561 %page;
1562 %include baud_rates;
1563 %page;
1564 %include channel_manager_dcls;
1565 %page;
1566 %include dn355_data;
1567 %page;
1568 %include dn355_mailbox;
1569 %page;
1570 %include dn355_messages;
1571 %page;
1572 %include fnp_mpx_msg_;
1573 %page;
1574 %include fnp_queue_entry;
1575 %page;
1576 %include io_manager_dcls;
1577 %page;
1578 %include lct;
1579 %page;
1580 %include line_types;
1581 %page;
1582 %include mailbox_ops;
1583 %page;
1584 %include mcs_interrupt_info;
1585 %page;
1586 %include net_event_message;
1587 %page;
1588 %include pcb;
1589 %page;
1590 %include tty_buf;
1591 %page;
1592 %include tty_buffer_block;
1593 %page;
1594 %include tty_space_man_dcls;
1595 %page;
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851 end dn355;