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 
  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 
  61 
  62 
  63 
  64 
  65 
  66 
  67 
  68 
  69 
  70 
  71 
  72 
  73 
  74 
  75 
  76 
  77 
  78 
  79 
  80 
  81 
  82 
  83 
  84 
  85 
  86 
  87 
  88 
  89 
  90 
  91 
  92 
  93 
  94 
  95 
  96 
  97 
  98 
  99 
 100 
 101 
 102 
 103 
 104 
 105 
 106 
 107 
 108 
 109 
 110 
 111 
 112 
 113 
 114 
 115 
 116 
 117 
 118 
 119 
 120 
 121 
 122 
 123 
 124 
 125 
 126 
 127 
 128 
 129 
 130 
 131 
 132 
 133 
 134 
 135 disk_control:
 136      proc;
 137 
 138 dcl       a_pvtx                 fixed bin;                 
 139 dcl       a_coreadd              fixed bin (24);            
 140 dcl       a_devadd               bit (18) aligned;          
 141 dcl       a_intrpt               fixed bin (1);             
 142 dcl       a_queue_length         fixed bin;                 
 143 dcl       a_sect_off             fixed bin (4);             
 144 dcl       a_n_sectors            fixed bin;                 
 145 
 146 dcl       pvtx                   fixed bin;                 
 147 dcl       coreadd                fixed bin (24);
 148 dcl       sect_off               fixed bin (4);
 149 dcl       n_sectors              fixed bin;
 150 dcl       record_offset          fixed bin;
 151 
 152 
 153 
 154 dcl       bootload_sw            bit (1) aligned;           
 155 dcl       call_run_sx            fixed bin;                 
 156 dcl       channel_time           fixed bin (52);            
 157 dcl       command                bit (6) aligned;           
 158 dcl       cylinder               fixed bin (12);            
 159 dcl       dcdcwp                 ptr;                       
 160 dcl       dddcwp                 ptr;                       
 161 dcl       dev                    unsigned fixed bin (6);    
 162 dcl       devadd                 fixed bin (18);            
 163 dcl       dev_count              fixed bin;                 
 164 dcl       entry_time             fixed bin (52);            
 165 dcl       errcd                  fixed bin (35);            
 166 dcl       i                      fixed bin;                 
 167 dcl       intrpt                 bit (1);                   
 168 dcl       io_type                fixed bin;                 
 169 dcl       lcp                    ptr;                       
 170 dcl       level                  fixed bin (3);             
 171 dcl       majstat                fixed bin (5);             
 172 dcl       mask                   fixed bin (71) aligned;    
 173 dcl       masked                 bit (1);                   
 174 dcl       meter_start_time       fixed bin (52);            
 175 dcl       name_rel               fixed bin (17);            
 176 dcl       pdi                    fixed bin (6) unsigned;    
 177 dcl       post_sw                bit (1) aligned;           
 178 dcl       ptp                    ptr;                       
 179 dcl       qrp                    bit (18) aligned;          
 180 dcl       qx                     fixed bin (8);             
 181 dcl       required               bit (1) aligned;           
 182 dcl       sector                 fixed bin (21);            
 183 dcl       sect_sw                bit (1);                   
 184 dcl       stat                   bit (36) aligned;          
 185 dcl       status_time            fixed bin (52);            
 186 dcl       sx                     fixed bin (8);             
 187 dcl       sysc                   fixed bin;                 
 188 dcl       substat                bit (6) aligned;           
 189 dcl       temp_time              fixed bin (52);            
 190 dcl       usurped                bit (1) aligned;           
 191 dcl       wait_time              fixed bin (52);            
 192 
 193 dcl       1 msg_buf              like io_msg aligned;       
 194 
 195 dcl       1 stat_entry           like io_status_entry;      
 196 
 197 dcl       error_table_$bad_arg   fixed bin (35) ext static;
 198 dcl       error_table_$io_configured
 199                                  fixed bin (35) ext static;
 200 
 201 dcl       pds$processid          ext bit (36);
 202 dcl       page_fault$disk_offline_event
 203                                  bit (36) aligned ext;
 204 dcl       tc_data$system_shutdown
 205                                  ext fixed bin;
 206 
 207 dcl       ANY                    bit (6) init ("000000"b) static options (constant);
 208                                                             
 209 dcl       (
 210           BOTH                   init ("1"b),
 211           SINGLE                 init ("0"b),
 212           ON                     init ("1"b),
 213           OFF                    init ("0"b),
 214           SUCCESS                init ("1"b),
 215           FAILURE                init ("0"b)
 216           )                      bit (1) aligned static options (constant);
 217 dcl       IDCW                   bit (3) init ("7"b3) static options (constant);
 218 dcl       (
 219           WRITE                  init ("31"b3),
 220           READ                   init ("25"b3),
 221           RESET_STATUS           init ("40"b3),
 222           UNLOAD                 init ("72"b3)
 223           )                      bit (6) static options (constant);
 224 dcl       UNLOCK                 bit (36) aligned init ((36)"0"b) static options (constant);
 225 dcl       (
 226           ANNOUNCE_RECONNECT_DELTA
 227                                  fixed bin (35) init (30000000),
 228                                                             
 229           DISK_POLLING_TIME      fixed bin (35) init (2000000),
 230                                                             
 231           INOP_POLLING_TIME      fixed bin (35) init (5000000),
 232                                                             
 233           BROKEN_POLLING_TIME    fixed bin (35) init (180000000),
 234                                                             
 235           CHANNEL_POLLING_TIME   fixed bin (35) init (60000000)
 236                                                             
 237           )                      static options (constant);
 238 
 239 dcl       bootload_disk_post     entry (fixed bin (24), fixed bin (35));
 240 dcl       seek_512               bit (6) init ("30"b3) static options (constant);
 241 dcl       syserr                 entry options (variable);
 242 dcl       syserr$binary          entry options (variable);
 243 dcl       pxss$notify            entry (bit (36) aligned);
 244 dcl       page$done              entry (fixed bin (24), fixed bin (35));
 245 dcl       pmut$wire_and_mask     entry (fixed bin (71) aligned, ptr);
 246 dcl       pmut$unwire_unmask     entry (fixed bin (71) aligned, ptr);
 247 dcl       dctl$disk_inter        entry (fixed bin (35), fixed bin (3), bit (36) aligned);
 248 dcl       vtoc_interrupt         entry (fixed bin (24), fixed bin (35));
 249 dcl       ioi_masked$online_device_count
 250                                  entry (char (*)) returns (fixed bin);
 251 dcl       ioi_masked$interrupt   entry (fixed bin (35), fixed bin (3), bit (36) aligned);
 252 
 253 dcl       (abs, addr, addrel, bin, bit, clock, convert, divide, fixed, float, lbound, length, hbound, max, mod, null, ptr,
 254           rel, stacq, string, substr, unspec)
 255                                  builtin;
 256 ^L
 257 dcl       ME                     char (16) static options (constant) init ("disk_control");
 258 
 259 dcl       dev_mask               (0:63) bit (72) aligned static options (constant)
 260                                  init ("100000000000000000000000000000000000000000000000000000000000000000000000"b,
 261                                  "010000000000000000000000000000000000000000000000000000000000000000000000"b,
 262                                  "001000000000000000000000000000000000000000000000000000000000000000000000"b,
 263                                  "000100000000000000000000000000000000000000000000000000000000000000000000"b,
 264                                  "000010000000000000000000000000000000000000000000000000000000000000000000"b,
 265                                  "000001000000000000000000000000000000000000000000000000000000000000000000"b,
 266                                  "000000100000000000000000000000000000000000000000000000000000000000000000"b,
 267                                  "000000010000000000000000000000000000000000000000000000000000000000000000"b,
 268                                  "000000001000000000000000000000000000000000000000000000000000000000000000"b,
 269                                  "000000000100000000000000000000000000000000000000000000000000000000000000"b,
 270                                  "000000000010000000000000000000000000000000000000000000000000000000000000"b,
 271                                  "000000000001000000000000000000000000000000000000000000000000000000000000"b,
 272                                  "000000000000100000000000000000000000000000000000000000000000000000000000"b,
 273                                  "000000000000010000000000000000000000000000000000000000000000000000000000"b,
 274                                  "000000000000001000000000000000000000000000000000000000000000000000000000"b,
 275                                  "000000000000000100000000000000000000000000000000000000000000000000000000"b,
 276                                  "000000000000000010000000000000000000000000000000000000000000000000000000"b,
 277                                  "000000000000000001000000000000000000000000000000000000000000000000000000"b,
 278                                  "000000000000000000100000000000000000000000000000000000000000000000000000"b,
 279                                  "000000000000000000010000000000000000000000000000000000000000000000000000"b,
 280                                  "000000000000000000001000000000000000000000000000000000000000000000000000"b,
 281                                  "000000000000000000000100000000000000000000000000000000000000000000000000"b,
 282                                  "000000000000000000000010000000000000000000000000000000000000000000000000"b,
 283                                  "000000000000000000000001000000000000000000000000000000000000000000000000"b,
 284                                  "000000000000000000000000100000000000000000000000000000000000000000000000"b,
 285                                  "000000000000000000000000010000000000000000000000000000000000000000000000"b,
 286                                  "000000000000000000000000001000000000000000000000000000000000000000000000"b,
 287                                  "000000000000000000000000000100000000000000000000000000000000000000000000"b,
 288                                  "000000000000000000000000000010000000000000000000000000000000000000000000"b,
 289                                  "000000000000000000000000000001000000000000000000000000000000000000000000"b,
 290                                  "000000000000000000000000000000100000000000000000000000000000000000000000"b,
 291                                  "000000000000000000000000000000010000000000000000000000000000000000000000"b,
 292                                  "000000000000000000000000000000001000000000000000000000000000000000000000"b,
 293                                  "000000000000000000000000000000000100000000000000000000000000000000000000"b,
 294                                  "000000000000000000000000000000000010000000000000000000000000000000000000"b,
 295                                  "000000000000000000000000000000000001000000000000000000000000000000000000"b,
 296                                  "000000000000000000000000000000000000100000000000000000000000000000000000"b,
 297                                  "000000000000000000000000000000000000010000000000000000000000000000000000"b,
 298                                  "000000000000000000000000000000000000001000000000000000000000000000000000"b,
 299                                  "000000000000000000000000000000000000000100000000000000000000000000000000"b,
 300                                  "000000000000000000000000000000000000000010000000000000000000000000000000"b,
 301                                  "000000000000000000000000000000000000000001000000000000000000000000000000"b,
 302                                  "000000000000000000000000000000000000000000100000000000000000000000000000"b,
 303                                  "000000000000000000000000000000000000000000010000000000000000000000000000"b,
 304                                  "000000000000000000000000000000000000000000001000000000000000000000000000"b,
 305                                  "000000000000000000000000000000000000000000000100000000000000000000000000"b,
 306                                  "000000000000000000000000000000000000000000000010000000000000000000000000"b,
 307                                  "000000000000000000000000000000000000000000000001000000000000000000000000"b,
 308                                  "000000000000000000000000000000000000000000000000100000000000000000000000"b,
 309                                  "000000000000000000000000000000000000000000000000010000000000000000000000"b,
 310                                  "000000000000000000000000000000000000000000000000001000000000000000000000"b,
 311                                  "000000000000000000000000000000000000000000000000000100000000000000000000"b,
 312                                  "000000000000000000000000000000000000000000000000000010000000000000000000"b,
 313                                  "000000000000000000000000000000000000000000000000000001000000000000000000"b,
 314                                  "000000000000000000000000000000000000000000000000000000100000000000000000"b,
 315                                  "000000000000000000000000000000000000000000000000000000010000000000000000"b,
 316                                  "000000000000000000000000000000000000000000000000000000001000000000000000"b,
 317                                  "000000000000000000000000000000000000000000000000000000000100000000000000"b,
 318                                  "000000000000000000000000000000000000000000000000000000000010000000000000"b,
 319                                  "000000000000000000000000000000000000000000000000000000000001000000000000"b,
 320                                  "000000000000000000000000000000000000000000000000000000000000100000000000"b,
 321                                  "000000000000000000000000000000000000000000000000000000000000010000000000"b,
 322                                  "000000000000000000000000000000000000000000000000000000000000001000000000"b,
 323                                  "000000000000000000000000000000000000000000000000000000000000000100000000"b);
 324 ^L
 325 
 326 
 327 
 328 
 329 
 330 
 331 
 332 
 333 
 334 
 335 
 336 
 337 
 338 
 339 
 340 
 341 
 342 
 343 
 344 
 345 
 346 
 347 
 348 
 349 
 350 
 351 
 352 
 353 
 354 
 355 
 356 
 357 
 358 ^L
 359 
 360 
 361 
 362 
 363 
 364 
 365 write_sectors:
 366      entry (a_pvtx, a_coreadd, a_devadd, a_sect_off, a_n_sectors);
 367 
 368           io_type = VTOC_WRITE;
 369           goto go_sector;
 370 
 371 
 372 read_sectors:
 373      entry (a_pvtx, a_coreadd, a_devadd, a_sect_off, a_n_sectors);
 374 
 375           io_type = VTOC_READ;
 376 go_sector:
 377           devadd = bin (a_devadd, 18);                      
 378           coreadd = a_coreadd;                              
 379 
 380           sect_off = a_sect_off;                            
 381           n_sectors = a_n_sectors;
 382           goto go_masked;                                   
 383 
 384 
 385 test_drive:
 386      entry (a_pvtx);                                        
 387 
 388           io_type = TEST;
 389           coreadd = bin (RESET_STATUS, 24);                 
 390           goto go_test;
 391 
 392 
 393 
 394 unload_drive:
 395      entry (a_pvtx);                                        
 396 
 397           io_type = TEST;
 398           coreadd = bin (UNLOAD, 24);                       
 399 go_test:
 400           sect_off = 0;                                     
 401           n_sectors = 0;                                    
 402           devadd = 0;                                       
 403 
 404 
 405 
 406 go_masked:
 407           call pmut$wire_and_mask (mask, ptp);              
 408           masked = "1"b;                                    
 409           intrpt = "0"b;
 410           goto go_common;
 411 
 412 
 413 
 414 
 415 disk_write:
 416      entry (a_pvtx, a_coreadd, a_devadd, a_intrpt);
 417 
 418           io_type = PAGE_WRITE;
 419           goto go_page;
 420 
 421 disk_read:
 422      entry (a_pvtx, a_coreadd, a_devadd, a_intrpt);
 423 
 424           io_type = PAGE_READ;
 425 go_page:
 426           masked = "0"b;                                    
 427           devadd = bin (a_devadd, 18);                      
 428           coreadd = a_coreadd;                              
 429           sect_off = 0;                                     
 430           n_sectors = 0;
 431           if a_intrpt ^= 0 then
 432                intrpt = "1"b;                               
 433           else intrpt = "0"b;
 434 ^L
 435 
 436 
 437 
 438 go_common:
 439           entry_time = clock ();
 440           sect_sw = sector_map (io_type);
 441           bootload_sw = bootload_map (io_type);
 442           pvtep = addr (addr (pvt$array) -> pvt_array (a_pvtx));
 443                                                             
 444           pvtdip = addr (pvte.dim_info);                    
 445           sx = pvtdi.sx;                                    
 446           call setup;                                       
 447           call lock (addr (disktab.call_lock_meters));      
 448 
 449           dev = pvte.logical_area_number;                   
 450           pdi = disktab.devtab (dev).pdi;                   
 451           dp = addr (disktab.devtab (pdi));                 
 452 
 453 
 454 
 455           if devtab.abandoned then do;                      
 456                errcd = 0;                                   
 457                if ^write_map (io_type) then do;             
 458                     erfp = addr (errcd);                    
 459                     errflags.device_inoperative = "1"b;     
 460                end;
 461                call unlock;                                 
 462                call post;                                   
 463                go to call_exit;                             
 464           end;
 465 
 466 
 467 
 468           disktab.alloc_wait_meters.count = disktab.alloc_wait_meters.count + 1;
 469           if ^get_free_q () then do;                        
 470                call lock_meter_start (addr (disktab.alloc_wait_meters));
 471                do while (^get_free_q ());                   
 472                     call call_run (sx);                     
 473                end;                                         Note
 474                call lock_meter_stop (addr (disktab.alloc_wait_meters));
 475           end;
 476 
 477 
 478 
 479 
 480           if pvte.is_sv then do;                            
 481                record_offset = mod (devadd, pvte.records_per_cyl);
 482                devadd = ((devadd - record_offset) * pvte.num_of_svs) + pvte.record_factor + record_offset;
 483           end;
 484           sector = devadd * sect_per_rec (pvte.device_type);
 485           cylinder = divide (sector, pvtdi.usable_sect_per_cyl, 12, 0);
 486           sector = sector + cylinder * pvtdi.unused_sect_per_cyl;
 487           sector = sector + sect_off;                       
 488 
 489 
 490 
 491           quentry.intrpt = intrpt;                          
 492           quentry.used = "1"b;                              
 493           quentry.type = io_type;                           
 494           quentry.coreadd = bit (coreadd, 24);              
 495 
 496           quentry.pvtx = a_pvtx;                            
 497           quentry.pdi = pdi;                                
 498           quentry.dev = dev;                                
 499           quentry.cylinder = cylinder;                      
 500 
 501           quentry.n_sectors = n_sectors;                    
 502           quentry.sector = bit (sector, 21);                
 503 
 504 
 505 
 506           quentry.time = entry_time;
 507 ^L
 508 
 509 
 510 
 511           if ^(disktab.dev_busy | disktab.dev_queued) & dev_mask (pdi) then
 512                do i = 1 to disktab.nchan;                   
 513                cp = addr (ptr (disksp, disktab.channels) -> disk_channel_table (i));
 514                                                             
 515                if chantab.in_use & ^chantab.active then do; 
 516                     call gotwork;                           
 517                     go to working;                          
 518                end;
 519           end;
 520 
 521           call add_wq;                                      
 522 
 523 
 524 
 525 working:
 526           call unlock;                                      
 527 
 528 call_exit:
 529           if masked then
 530                call pmut$unwire_unmask (mask, ptp);         
 531 
 532           return;
 533 ^L
 534 
 535 
 536 esd_reset_locks:
 537      entry;
 538 
 539           disksp = addr (disk_seg$);
 540 
 541           unspec (disk_data.free_q) = "0"b;                 
 542           disk_data.free_q.depth = disk_data.free_q_size;   
 543 
 544 
 545 
 546 
 547 
 548 
 549           unspec (disk_data.lock) = unspec (disk_data.lock) & "0"b;
 550 
 551           do qx = 1 to disk_data.free_q_size;               
 552                qp = addr (disk_data.free_q_entries (qx));
 553                qrp = rel (qp);
 554 
 555                call add_free_q;                             
 556           end;
 557 
 558           do sx = 1 to disk_data.subsystems;
 559                call setup;                                  
 560                call unlock;                                 
 561 
 562                call lock (addr (disktab.call_lock_meters)); 
 563 
 564                do dev = disktab.first_dev to disktab.last_dev;
 565                                                             
 566                     dp = addr (disktab.devtab (dev));       
 567                     devtab.broken, devtab.was_broken, devtab.inop = "0"b;
 568                                                             
 569                     devtab.cylinder = 0;                    
 570                     unspec (devtab.wq) = "0"b;              
 571 
 572 
 573 
 574                     do i = 0 to MAX_IO_TYPE;
 575                          devtab.forward = "1"b;
 576                          devtab.opt_info (i).depth = 0;
 577                     end;
 578                end;
 579 
 580                cp = ptr (disksp, disktab.channels);         
 581                do i = 1 to disktab.nchan;                   
 582                     cp -> disk_channel_table (i).active = "0"b;
 583                                                             
 584                     cp -> disk_channel_table (i).inop = "0"b;
 585                                                             
 586                     cp -> disk_channel_table (i).broken = "0"b;
 587                                                             
 588                     if ^(cp -> disk_channel_table (i).ioi_use) &
 589                        ^(cp -> disk_channel_table (i).in_use) then do;
 590                         cp -> disk_channel_table (i).in_use = "1"b;
 591                         disktab.channels_online = disktab.channels_online+1;
 592                       end;
 593                     cp -> disk_channel_table (i).erct = 0;  
 594                end;
 595 
 596                disktab.dev_busy = "0"b;                     
 597                disktab.dev_queued = "0"b;                   
 598 
 599                call run;                                    
 600                call unlock;                                 
 601           end;
 602 
 603           return;
 604 ^L
 605 
 606 
 607 usurp_channel:
 608      entry (a_sx, a_chx, a_required, a_iom_chx, a_statusp); 
 609 
 610 dcl       a_sx                   fixed bin (8);             
 611 dcl       a_chx                  fixed bin (35);            
 612 dcl       a_required             bit (1) aligned;           
 613 
 614 dcl       chx                    fixed bin (35);            
 615 
 616           sx = a_sx;                                        
 617           required = a_required;                            
 618           chx = a_chx;                                      
 619           call setup;                                       
 620           cp = addr (ptr (disksp, disktab.channels) -> disk_channel_table (chx));
 621                                                             
 622 
 623           call pmut$wire_and_mask (mask, ptp);              
 624           call lock (addr (disktab.call_lock_meters));      
 625 
 626           usurped = (required | ^(chantab.broken | chantab.inop)) &
 627                                                             
 628                ((disktab.channels_online > 1) | ^chantab.in_use
 629                | (ioi_masked$online_device_count (disk_data.name (sx)) = 0));
 630                                                             
 631 
 632           if usurped then do;                               
 633                if chantab.in_use then                       
 634                     disktab.channels_online = disktab.channels_online - 1;
 635                chantab.in_use = "0"b;                       
 636                chantab.broken, chantab.inop = "0"b;         
 637           end;
 638 
 639           call unlock;                                      
 640           call pmut$unwire_unmask (mask, ptp);              
 641 
 642           if usurped then do;                               
 643                do while (chantab.active);                   
 644                end;
 645                a_iom_chx = chantab.chx;
 646                a_statusp = chantab.statusp;
 647                chantab.ioi_use = "1"b;                      
 648           end;
 649           else do;
 650                a_iom_chx = 0;
 651                a_statusp = null ();
 652           end;
 653 
 654           return;
 655 ^L
 656 cede_channel:
 657      entry (a_sx, a_chx, a_iom_chx, a_statusp);             
 658 
 659 dcl       a_iom_chx              fixed bin (35) parameter;
 660 dcl       a_statusp              ptr parameter;
 661 
 662 dcl       iom_chx                fixed bin (35);
 663 dcl       statusp                ptr;
 664 
 665           sx = a_sx;                                        
 666           chx = a_chx;                                      
 667           iom_chx = a_iom_chx;
 668           statusp = a_statusp;
 669           call setup;                                       
 670           cp = addr (ptr (disksp, disktab.channels) -> disk_channel_table (chx));
 671                                                             
 672 
 673           chantab.chx = iom_chx;
 674           chantab.statusp = statusp;
 675           chantab.ioi_use = "0"b;                           
 676           chantab.in_use = "1"b;                            
 677           disktab.channels_online = disktab.channels_online + 1;
 678 
 679           return;
 680 ^L
 681 
 682 
 683 add_channel:
 684      entry (a_sx, a_chx, a_code);
 685 
 686 dcl       a_code                 fixed bin (35) parameter;
 687 
 688           sx = a_sx;
 689           chx = a_chx;
 690           call setup;
 691           cp = addr (ptr (disksp, disktab.channels) -> disk_channel_table (chx));
 692           call pmut$wire_and_mask (mask, ptp);
 693           call lock (addr (disktab.call_lock_meters));
 694           if chantab.broken then do;
 695                chantab.broken = "0"b;
 696                chantab.in_use = "1"b;
 697                disktab.channels_online = disktab.channels_online + 1;
 698           end;
 699           else errcd = error_table_$io_configured;
 700           call unlock;
 701           call pmut$unwire_unmask (mask, ptp);
 702           if errcd = 0 then
 703                call syserr (ANNOUNCE, "^a: Adding channel ^a.", ME, chantab.chanid);
 704           a_code = errcd;
 705           return;
 706 ^L
 707 
 708 
 709 disk_run:
 710      entry;                                                 
 711 
 712           entry_time = clock ();                            
 713 
 714           disksp = addr (disk_seg$);                        
 715 
 716           do sx = 1 to disk_data.subsystems;                
 717                call setup;                                  
 718                call lock (addr (disktab.run_lock_meters));  
 719                call run;                                    
 720                call unlock;                                 
 721           end;
 722 
 723           return;
 724 
 725 
 726 
 727 
 728 
 729 call_run:
 730      entry (a_sx);
 731 
 732 
 733           entry_time = clock ();
 734 
 735           sx = a_sx;                                        
 736           call setup;
 737           call run;
 738 
 739 
 740 
 741           call_run_sx = a_sx;                               
 742           do sx = 1 to disk_data.subsystems;
 743                if sx ^= call_run_sx then do;
 744                     call setup;
 745                     if stacq (disktab.lock, pds$processid, UNLOCK) then do;
 746                                                             
 747                          call run;
 748                          call unlock;
 749                     end;
 750                end;
 751           end;
 752           sx = call_run_sx;
 753           call setup;                                       
 754           return;
 755 ^L
 756 
 757 
 758 run:
 759      proc;
 760 
 761 
 762 
 763           do i = 1 to disktab.nchan;                        
 764                cp = addr (ptr (disksp, disktab.channels) -> disk_channel_table (i));
 765                                                             
 766 
 767                if chantab.inop & ^chantab.in_use then       
 768                     if clock () - chantab.connect_time > CHANNEL_POLLING_TIME then do;
 769                          chantab.in_use = "1"b;             
 770                          disktab.channels_online = disktab.channels_online + 1;
 771                     end;
 772 
 773 
 774 
 775 
 776 
 777 
 778 
 779 
 780 
 781 
 782                if ^chantab.active then                      
 783                     call getwork;                           
 784 
 785                else do;                                     
 786                     status_time = clock ();                 
 787                     io_status_entry_ptr = addr (stat_entry);
 788                     call io_manager$get_status ((chantab.chx), io_status_entry_ptr);
 789                                                             
 790                     io_status_word_ptr = addr (stat_entry.word1);
 791                     if  io_status_word.t then do; 
 792                          chantab.status_from_run = chantab.status_from_run + 1;
 793                          level = 3;                         
 794                          call check_stat;                   
 795 
 796                          if post_sw then do;                
 797                               call unlock;                  
 798                               call post;                    
 799                               call lock (addr (disktab.call_lock_meters));
 800                                                             
 801                          end;
 802                     end;
 803 
 804                     else if chantab.connect_time + DISK_POLLING_TIME < status_time then do;
 805                                                             
 806                          idcwp = addr (chantab.scdcw);      
 807                          dev = fixed (idcw.device, 6);      
 808                          pdi = disktab.devtab (dev).pdi;    
 809                          if chantab.reconnect_announce_time < status_time then do;
 810                               chantab.reconnect_announce_time = status_time + ANNOUNCE_RECONNECT_DELTA;
 811                               sysc = ANNOUNCE;
 812                          end;
 813                          else sysc = LOG;
 814                          call syserr (sysc, "^a: Reconnected ^a I/O on ^a (channel ^a).", ME,
 815                               IO_TYPE (ptr (disksp, chantab.qrp) -> quentry.type), disk_name (SINGLE), chantab.chanid);
 816                          call connect (idcwp);              
 817                     end;
 818                end;
 819           end;
 820 
 821 
 822 
 823 
 824           do dev = disktab.first_dev to disktab.last_dev;   
 825                pdi = disktab.devtab (dev).pdi;              
 826                if pdi = dev then do;                        
 827                     dp = addr (disktab.devtab (pdi));       
 828 
 829                     if  devtab.inop then          
 830                          if clock () - devtab.time_inop > INOP_POLLING_TIME then do;
 831                               disktab.dev_busy = disktab.dev_busy & ^dev_mask (pdi);
 832                          end;                               
 833                          else ;
 834 
 835                     else if devtab.broken then              
 836                          if clock () - devtab.time_inop > BROKEN_POLLING_TIME then do;
 837                               devtab.inop = "1"b;           
 838                               devtab.was_broken = "1"b;     
 839                               pvtep = addr (addr (pvt$array) -> pvt_array (devtab.pvtx));
 840                               call set_pvte_inop (OFF);
 841                               devtab.broken = "0"b;         
 842                          end;
 843                          else ;
 844                end;
 845           end;
 846 
 847           return;
 848 
 849 
 850      end run;
 851 ^L
 852 
 853 
 854 disk_inter:
 855      entry (idx, ilevel, istat);                            
 856 
 857 dcl       idx                    fixed bin (35),            
 858           istat                  bit (36) aligned,          
 859           ilevel                 fixed bin (3);             
 860 
 861 dcl       int_idx                fixed bin (35);            
 862 
 863           int_idx = idx;
 864           sx = divide (int_idx, dskdcl_chans_per_subsys, 17, 0);
 865                                                             
 866           call setup;                                       
 867 
 868           i = int_idx - sx * dskdcl_chans_per_subsys + 1;   
 869           cp = addr (ptr (disksp, disktab.channels) -> disk_channel_table (i));
 870 
 871           level = ilevel;                                   
 872           stat = istat;
 873           if level = 7 then do;
 874                call check_special_stat;
 875                return;
 876           end;
 877 
 878 
 879           io_status_word_ptr = chantab.statusp;             
 880 
 881           if ^io_status_word.t then
 882                if level >= 3 then do;
 883                     chantab.no_status_terminate = chantab.no_status_terminate + 1;
 884                     return;
 885                end;
 886 
 887 
 888           if ^chantab.ioi_use then do;                      
 889                call lock (addr (disktab.int_lock_meters));  
 890                io_status_entry_ptr = addr (stat_entry);     
 891                unspec (io_status_entry) = ""b;
 892                if  level = 3 then do;             
 893                     call io_manager$get_status ((chantab.chx), io_status_entry_ptr);
 894                     io_status_word_ptr = addr (io_status_entry.word1);
 895                     if ^io_status_word.t then do;
 896                          chantab.no_io_terminate = chantab.no_io_terminate + 1;
 897                          call unlock;
 898                          return;
 899                     end;
 900                end;
 901                call check_stat;                             
 902                call unlock;                                 
 903 
 904                if post_sw then                              
 905                     call post;
 906           end;
 907 
 908           else                                              
 909                call ioi_masked$interrupt ((chantab.ioi_ctx), level, stat);
 910 
 911           return;                                           
 912 ^L
 913 check_special_stat:
 914      proc;
 915 
 916           io_special_status_ptr = addr (stat);              
 917           if ^io_special_status.t then
 918                return;
 919 
 920           dev = fixed (io_special_status.device, 6);        
 921           if dev = 0 & disktab.first_dev ^= 0 then          
 922                go to ioi_special;                           
 923           if dev > disktab.last_dev then
 924                return;                                      
 925 
 926           dp = addr (disktab.devtab (dev));                 
 927           pdi = devtab.pdi;                                 
 928 
 929           pvtx = devtab.pvtx;                               
 930           if pvtx = 0 then
 931                return;                                      
 932 
 933 
 934 
 935           pvtep = addr (pvt_array (pvtx));                  
 936 
 937           if pvte.storage_system then do;                   
 938                call lock (addr (disktab.int_lock_meters));  
 939 
 940                dp = addr (disktab.devtab (pdi));
 941                if  devtab.broken then do;         
 942                     call syserr (ANNOUNCE, "^a: Placing ^a in operation.", ME, disk_name (BOTH));
 943                     call set_pvte_inop (OFF);               
 944                     devtab.inop = "1"b;                     
 945                     devtab.was_broken = "1"b;               
 946                     devtab.broken = "0"b;                   
 947                end;
 948 
 949                else if devtab.inop then do;                 
 950                     devtab.inop = "0"b;                     
 951                     disktab.dev_busy = disktab.dev_busy & ^dev_mask (pdi);
 952                end;
 953 
 954                call call_run (sx);                          
 955 
 956                call unlock;                                 
 957           end;
 958 
 959           else do;                                          
 960 ioi_special:
 961                call ioi_masked$interrupt ((chantab.ioi_ctx), level, stat);
 962           end;                                              
 963 
 964           return;
 965 
 966      end check_special_stat;
 967 ^L
 968 
 969 
 970 check_stat:
 971      procedure;
 972 
 973           errcd = 0;                                        
 974           erfp = addr (errcd);
 975           post_sw = "0"b;                                   
 976 
 977           if ^chantab.active then do;                       
 978                chantab.terminate_not_active = chantab.terminate_not_active + 1;
 979                call syserr (JUST_LOG, "^a: Unexpected IOM status ^24.3b for ^a (channel ^a).", ME,
 980                     string (io_status_word), disk_data.name (sx), chantab.chanid);
 981                return;
 982           end;
 983 
 984           status_time = clock ();
 985 
 986           qrp = chantab.qrp;                                
 987           qp = ptr (disksp, qrp);
 988           dev = quentry.dev;                                
 989           pdi = quentry.pdi;                                
 990           coreadd = bin (quentry.coreadd, 24);              
 991           pvtx = quentry.pvtx;                              
 992           sect_sw = sector_map (quentry.type);
 993           bootload_sw = bootload_map (quentry.type);
 994 
 995           pvtep = addr (addr (pvt$array) -> pvt_array (pvtx));
 996                                                             
 997           dp = addr (disktab.devtab (pdi));                 
 998 
 999 
1000 
1001 
1002           io_type = quentry.type;
1003 
1004 
1005 
1006 
1007           if level = 3 then do;                             
1008                chantab.active = "0"b;                       
1009                disktab.dev_busy = disktab.dev_busy & ^dev_mask (pdi);
1010                                                             
1011 
1012 
1013 
1014                if  chantab.rsr then do;           
1015                     if (string (io_status_word) & disk_data.status_mask) then
1016                                                             
1017                          chantab.rsr = "0"b;                
1018                     unspec (io_status_entry.detailed_status (*)) = unspec (chantab.detailed_status (*));
1019                                                             
1020 
1021                     io_status_word_ptr = addr (chantab.status);
1022                                                             
1023                     command = chantab.command;              
1024                     call extract_status;                    
1025                     call handle_error;                      
1026 
1027                     chantab.rsr = "0"b;                     
1028                end;
1029 ^L
1030 
1031 
1032                else if string (io_status_word) & disk_data.status_mask then do;
1033                     call extract_status;                    
1034                     call interpret_status;                  
1035                     call get_disk_command;                  
1036 
1037                     if disk_error_interp.rsr & (io_status_entry.detailed_status (1) = ""b) then do;
1038                                                             
1039                          chantab.rsr = "1"b;                
1040                          chantab.status = string (io_status_word);
1041                                                             
1042                          chantab.action_code = io_status_entry.action_code;
1043                          chantab.command = command;         
1044 
1045                          idcwp = addr (chantab.dscdcw);
1046                          idcw.device = bit (dev);
1047                          call connect (idcwp);              
1048                     end;
1049 
1050                     else                                    
1051                          call handle_error;                 
1052                end;
1053 ^L
1054 
1055 
1056                else if io_status_entry.tally_residue ^= 0 then do;
1057                     majstat = 20;
1058                     substat = ANY;
1059                     call handle_error;                      
1060                end;
1061 
1062 
1063 
1064                else do;                                     
1065                     post_sw = "1"b;                         
1066 
1067                     if io_status_word.sub & "010011"b then do;
1068                                                             
1069                          disktab.edac_errors = disktab.edac_errors + 1;
1070 
1071                          if io_status_word.sub & "010000"b then
1072                                                             
1073                               majstat = 22;
1074                          else                               
1075                               majstat = 21;
1076                          substat = ANY;
1077                          call interpret_status;             
1078                          call get_disk_command ();          
1079                          call printerr;                     
1080                     end;
1081 
1082                     devtab.inop = "0"b;                     
1083 
1084                     if devtab.was_broken | devtab.broken then do;
1085                                                             
1086                          devtab.was_broken = "0"b;          
1087                          devtab.broken = "0"b;
1088                          call set_pvte_inop (OFF);
1089                          call syserr (ANNOUNCE, "^a: ^a now operational.", ME, disk_name (BOTH));
1090                     end;
1091                     chantab.inop = "0"b;                    
1092                end;
1093 
1094           end;                                              
1095 ^L
1096 
1097 
1098           else if level = 1 then do;                        
1099                chantab.active = "0"b;                       
1100                disktab.dev_busy = disktab.dev_busy & ^dev_mask (pdi);
1101                                                             
1102                majstat = 19;
1103                substat = ANY;
1104                call handle_error;                           
1105           end;
1106 
1107 
1108           else return;                                      
1109 ^L
1110 
1111 
1112           if post_sw then do;
1113                if io_type = TEST then do;
1114                     pvte.testing = "0"b;
1115                     post_sw = "0"b;
1116                end;                                         
1117                else do;
1118                     status_time = clock ();                 
1119                     channel_time = status_time - chantab.connect_time;
1120                                                             
1121                     wait_time = status_time - quentry.time;
1122 
1123                     optp = addr (devtab.opt_info (quentry.type));
1124                                                             
1125 
1126                     opt_info.channel_wait = opt_info.channel_wait + channel_time;
1127                     opt_info.queue_wait = opt_info.queue_wait + wait_time;
1128 
1129 
1130 
1131                     if errcd ^= 0                           
1132                          then
1133                          disktab.ferrors = disktab.ferrors + 1;
1134                end;
1135 
1136                call add_free_q;                             
1137           end;
1138 
1139           if ^chantab.active then                           
1140                call getwork;                                
1141 
1142           return;                                           
1143 ^L
1144 
1145 
1146 extract_status:
1147           proc;
1148 
1149                if  io_status_word.power then do;
1150                     majstat = 16;
1151                     substat = ANY;
1152                end;
1153                else if io_status_word.channel_stat then do;
1154                     majstat = 17;
1155                     substat = io_status_word.channel_stat;
1156                end;
1157                else if io_status_word.central_stat then do;
1158                     majstat = 18;
1159                     substat = io_status_word.central_stat;
1160                end;
1161                else do;
1162                     majstat = bin (io_status_word.major, 4);
1163                     substat = io_status_word.sub;
1164                end;
1165 
1166 
1167           end extract_status;
1168 
1169 
1170 
1171 
1172 
1173 interpret_status:
1174           proc;
1175 
1176 
1177                dedp = addr (disk_error_data$);
1178                if pvte.is_sv then
1179                     dskerap = addrel (dedp, disk_error_data (majstat).finterp);
1180                else dskerap = addrel (dedp, disk_error_data (majstat).interp);
1181 
1182 
1183                name_rel = fixed (rel (addrel (dedp, disk_error_data (lbound (disk_error_data, 1)).namep)), 17);
1184                dskerp = addr (disk_status_interp_array (lbound (disk_status_interp_array, 1)));
1185                do i = lbound (disk_status_interp_array, 1) by 1 while (bin (rel (dskerp), 18) < name_rel);
1186                     dskerp = addr (disk_status_interp_array (i));
1187                     if (substat & disk_error_interp.bitmask) = disk_error_interp.bitson then
1188                          return;
1189                end;
1190 
1191 
1192           end interpret_status;
1193 
1194 
1195 
1196 
1197 
1198 get_disk_command:
1199           proc;
1200 
1201                idcwp = addrel (diskp, bin (io_status_entry.next_lpw_offset, 18) - disktab.abs_mem_addr - 1);
1202                                                             
1203                do while (idcw.code ^= IDCW);                
1204                     idcwp = addrel (idcwp, -1);
1205                end;
1206                command = idcw.command;                      
1207 
1208 
1209           end get_disk_command;
1210 ^L
1211 
1212 
1213 printerr:
1214           proc;
1215 
1216 dcl       type                   fixed bin;                 
1217 dcl       record_address         fixed bin (18);            
1218 dcl       mjsdp                  ptr;                       
1219 dcl       ssdp                   ptr;                       
1220 dcl       imu_detailed_status    (0:23) bit (8) based;      
1221 dcl       logical_rec_addr       fixed bin (17);            
1222 dcl       logical_sector         fixed bin (21);            
1223 dcl       sector_offset          fixed bin (17);            
1224 
1225                if devtab.broken then
1226                     return;                                 
1227 
1228                sector = bin (chantab.select_data.sector);   
1229                type = pvte.device_type;                     
1230                pvtdip = addr (pvte.dim_info);
1231                record_address =
1232                     divide (sector - (divide (sector, sect_per_cyl (type), 17, 0) * pvtdi.unused_sect_per_cyl),
1233                     sect_per_rec (type), 17, 0);
1234 
1235                if pvte.is_sv then do;
1236                     record_offset = mod (record_address, pvte.records_per_cyl);
1237                     logical_rec_addr =
1238                          divide ((record_address - pvte.record_factor - record_offset), pvte.num_of_svs, 17)
1239                          + record_offset;
1240                     sector_offset = mod (sector, sect_per_cyl (type));
1241                     logical_sector =
1242                          divide ((sector - (pvte.sv_num * sect_per_cyl (type)) - sector_offset), pvte.num_of_svs, 17)
1243                          + sector_offset;
1244                end;
1245                else do;
1246                     logical_rec_addr = record_address;
1247                     logical_sector = sector;
1248                end;
1249 
1250 
1251                if pvte.is_sv then
1252                     mjsdp = addrel (dedp, disk_error_data (majstat).fnamep);
1253                else mjsdp = addrel (dedp, disk_error_data (majstat).namep);
1254                ssdp = addrel (dedp, disk_error_interp.namep);
1255 
1256                unspec (msg_buf) = "0"b;                     
1257                io_msgp = addr (msg_buf);
1258                io_msg.level = bit (level, 3);
1259                io_msg.channel = chantab.chanid;
1260                io_msg.device = bit (dev);
1261                io_msg.type = chantab.action_code;
1262                io_msg.command = command;
1263                io_msg.status = string (io_status_word);
1264                io_msg.devname = disk_data.name (sx);
1265 
1266                if  devtab.broken | disk_error_interp.just_log then
1267                     sysc = JUST_LOG;
1268                else if mod (chantab.erct, 5) = 1 then
1269                     sysc = ANNOUNCE;
1270                else sysc = JUST_LOG;
1271                call syserr$binary (sysc, io_msgp, SB_disk_err, SBL_disk_err,
1272                     "^a: ^a ^[^12.3b^1s^;^1s^a^] for ^a (channel ^a).^/^2-rec ^o, sect ^o, main ^o^[^/^2-subvol ^a, logical rec ^o, logical sect ^o^;^3s^]^[^/^2-detailed status:^24( ^2.4b^).^;^s^]",
1273                     ME, mjsdp -> disk_status_descrip.chr, (level = 1), stat, ssdp -> disk_status_descrip.chr,
1274                     disk_name (SINGLE), chantab.chanid, record_address, sector, coreadd, pvte.is_sv, pvte.sv_name,
1275                     logical_rec_addr, logical_sector, (io_status_entry.detailed_status (1) ^= ""b),
1276                     addr (io_status_entry.detailed_status) -> imu_detailed_status);
1277 
1278                return;
1279 
1280 
1281           end printerr;
1282 ^L
1283 
1284 
1285 handle_error:
1286           proc;
1287 
1288 
1289                chantab.erct = chantab.erct + 1;
1290                disktab.errors = disktab.errors + 1;
1291 
1292                call interpret_status;                       
1293                if io_type = TEST then
1294                     idcwp = addr (chantab.rssdcw);
1295                else idcwp = addr (chantab.scdcw);
1296 
1297                if ^(io_type = TEST & ^disk_error_interp.bad_path) then
1298                     call printerr;                          
1299 
1300                if  chantab.erct <= disk_error_interp.max_retries & io_type ^= TEST then do;
1301                     if disk_error_interp.reseek then do;    
1302                          idcwp = addr (chantab.rstdcw);
1303                          idcw.device = bit (dev);
1304                          call connect (idcwp);              
1305                     end;
1306                     else do;                                
1307                          if disk_error_interp.bad_path then do;
1308                                                             
1309                               temp_time = clock ();
1310                               do while (clock () < temp_time + 750000);
1311                                                             
1312                               end;
1313                          end;
1314                          call connect (idcwp);
1315                     end;
1316                end;
1317 
1318                else if disk_error_interp.bad_dev then do;   
1319                     if  devtab.inop | devtab.broken | io_type = TEST then do;
1320                                                             
1321                          if ^devtab.broken then             
1322                               if quentry.type ^= TEST then
1323                                    call syserr (BEEP, "^a: ^a requires intervention.", ME, disk_name (SINGLE));
1324                          devtab.broken = "1"b;              
1325                          call set_pvte_inop (ON);
1326                          devtab.was_broken = "0"b;
1327                          devtab.inop = "0"b;                
1328                          devtab.time_inop = clock ();       Note
1329 
1330                          errflags.device_inoperative = "1"b;
1331                          post_sw = "1"b;                    
1332                     end;
1333 
1334                     else if tc_data$system_shutdown = 0 then do;
1335                                                             
1336                          devtab.inop = "1"b;                
1337                          disktab.dev_busy = disktab.dev_busy | dev_mask (pdi);
1338                                                             
1339                          devtab.time_inop = clock ();       Note
1340                          call add_wq;                       
1341                     end;
1342 
1343                     else do;                                
1344                          if quentry.type = TEST then
1345                               call set_pvte_inop (ON);
1346                          errflags.device_inoperative = "1"b;
1347                          post_sw = "1"b;                    
1348                     end;
1349                end;
1350                else if disk_error_interp.bad_addr then do;  
1351                     if write_map (quentry.type) then        
1352                          errflags.reassign_address = "1"b;  
1353                     else                                    
1354                          errflags.seg_unusable = "1"b;      
1355                     post_sw = "1"b;                         
1356                end;
1357 
1358                else if disk_error_interp.bad_path then do;  
1359                     if chantab.inop then do;                
1360                          chantab.broken = "1"b;
1361                          chantab.inop = "0"b;
1362                     end;
1363                     else do;                                
1364                          chantab.inop = "1"b;               
1365                          chantab.connect_time = clock ();   
1366                     end;
1367 
1368                     if disktab.channels_online > 1 then do;
1369                          call syserr (BEEP, "^a: Removing channel ^a.", ME, chantab.chanid);
1370                          chantab.in_use = "0"b;
1371                          disktab.channels_online = disktab.channels_online - 1;
1372                     end;
1373                     else do;
1374                          if bootload_sw then do;            
1375                               errflags.all_paths_bad = "1"b;
1376                               post_sw = "1"b;
1377                          end;
1378                          else if io_type = TEST then do;
1379                               call set_pvte_inop (ON);      
1380                               if (tc_data$system_shutdown ^= 0) then do;
1381                                   post_sw = "1"b;
1382                                   errflags.device_inoperative = "1"b;
1383                                   errflags.all_paths_bad = "1"b;
1384                                   return;
1385                               end;
1386 
1387                          end;
1388                          else if tc_data$system_shutdown ^= 0 then do;
1389                               errflags.device_inoperative = "1"b;
1390                                                             
1391                               errflags.all_paths_bad = "1"b;
1392                               post_sw = "1"b;
1393                          end;
1394                          else do;                           
1395                               chantab.erct = 0;
1396                               chantab.inop = "0"b;
1397                               call connect (addr (chantab.scdcw));
1398                          end;
1399 
1400 
1401 
1402 
1403                          do i = 1 to disktab.nchan;
1404                               lcp = addr (ptr (disksp, disktab.channels) -> disk_channel_table (i));
1405                               if ^(lcp -> chantab.ioi_use) then do;
1406                                                             
1407                                    if (lcp -> chantab.connect_time + CHANNEL_POLLING_TIME < clock ())
1408                                         | post_sw  then do;
1409                                                             
1410 
1411                                         lcp -> chantab.broken = "0"b;
1412                                                             
1413                                         lcp -> chantab.inop = "0"b;
1414                                                             
1415                                         lcp -> chantab.erct = 0;
1416                                                             
1417                                         lcp -> chantab.active = "0"b;
1418                                                             
1419 
1420                                         lcp -> chantab.in_use = "1"b;
1421 
1422 
1423                                         lcp -> chantab.connect_time = clock ();
1424                                         disktab.channels_online = disktab.channels_online + 1;
1425 
1426                                    end;
1427                               end;
1428                          end;
1429                          return;
1430                     end;
1431 
1432                     post_sw = "0"b;                         
1433                     call add_wq;                            
1434 
1435 
1436 
1437 
1438                     do i = 1 to disktab.nchan;              
1439                          cp = addr (ptr (disksp, disktab.channels) -> disk_channel_table (i));
1440                                                             
1441                          if chantab.in_use & ^chantab.active then do;
1442                               call getwork;
1443                               return;
1444                          end;
1445                     end;
1446                end;
1447                else if disk_error_interp.bad_mem then do;   
1448                     errflags.fatal_error = "1"b;
1449                     errflags.memory_unusable = "1"b;
1450                     post_sw = "1"b;
1451                end;
1452                else do;                                     
1453                     errflags.fatal_error = "1"b;
1454                     post_sw = "1"b;                         
1455                end;
1456 
1457                return;
1458 
1459 
1460           end handle_error;
1461 
1462      end check_stat;
1463 ^L
1464 
1465 
1466 getwork:
1467      proc;
1468 
1469           if ^chantab.in_use then
1470                return;                                      
1471 
1472           if ^disktab.dev_busy & disktab.dev_queued = "0"b then
1473                return;                                      
1474 
1475 
1476 
1477           do dev_count = lbound (disktab.devtab, 1) to hbound (disktab.devtab, 1);
1478                disktab.dev_index = disktab.dev_index + 1;   
1479                if disktab.dev_index > hbound (disktab.devtab, 1) then
1480                     disktab.dev_index = lbound (disktab.devtab, 1);
1481 
1482                dev = disktab.dev_index;
1483                pdi = disktab.devtab (dev).pdi;
1484 
1485                if ^disktab.dev_busy & dev_mask (pdi) then do;
1486                                                             
1487                     dp = addr (disktab.devtab (pdi));       
1488                     if ^devtab.broken                       
1489                          then
1490                          if devtab.wq.depth > 0             
1491                          then do;
1492                               qp = ptr (disksp, devtab.wq.head);
1493 
1494 
1495 
1496 
1497 
1498                               if devtab.wq.depth > 1 then
1499                                    if quentry.time >= (clock () - disk_data.stagnate_time) then
1500                                         call find_shortest_seek;
1501                                    else call comb;          
1502 
1503                               call del_q;                   
1504                               go to xfer_join;
1505                          end;
1506                end;
1507           end;
1508 
1509           return;                                           
1510 ^L
1511 
1512 
1513 find_shortest_seek:
1514           proc;
1515 
1516 dcl       (
1517           best_seek,                                        
1518           this_seek                                         
1519           )                      float bin (27),
1520           (
1521           best_pos_comb,                                    
1522           best_neg_comb,                                    
1523           this_comb                                         
1524           )                      fixed bin (35),
1525           best_qp                ptr,                       
1526           best_neg_qp            ptr,                       
1527           type                   fixed bin;                 
1528 
1529                cylinder = devtab.cylinder;
1530                best_seek = 1.0e+30;                         
1531 
1532 
1533 
1534 
1535 seek_loop:
1536                type = quentry.type;
1537                this_seek = float (abs (quentry.cylinder - cylinder) * devtab.opt_info (type).multiplier);
1538                if this_seek = 0.0 then
1539                     goto seek_on_cylinder;                  
1540 
1541                if this_seek < best_seek then do;            
1542                     best_seek = this_seek;
1543                     best_qp = qp;
1544                end;
1545 
1546 
1547 
1548                qrp = quentry.next;
1549                if qrp = "0"b then
1550                     goto seek_found;                        
1551 
1552                qp = ptr (disksp, qrp);                      
1553                goto seek_loop;
1554 
1555 
1556 seek_found:
1557                qp = best_qp;                                
1558 seek_on_cylinder:                                           
1559                qrp = rel (qp);
1560                return;
1561 ^L
1562 
1563 
1564 
1565 comb:
1566           entry;
1567 
1568                devtab.comb = devtab.comb + 1;
1569                cylinder = devtab.cylinder;
1570                best_pos_comb = 34359738367;
1571                best_neg_comb = -34359738367;
1572 
1573 
1574 
1575 
1576 comb_loop:
1577                if devtab.forward then
1578                     this_comb = quentry.cylinder - cylinder;
1579                else this_comb = cylinder - quentry.cylinder;
1580 
1581                if this_comb = 0 then                        
1582                     goto seek_on_cylinder;                  
1583                else if this_comb > 0                        
1584                then do;
1585                     if this_comb < best_pos_comb then do;
1586                          best_pos_comb = this_comb;
1587                          best_qp = qp;
1588                     end;
1589                end;
1590                else do;                                     
1591                     if this_comb > best_neg_comb then do;
1592                          best_neg_comb = this_comb;
1593                          best_neg_qp = qp;
1594                     end;
1595                end;
1596 
1597                qrp = quentry.next;
1598                if qrp = "0"b then
1599                     goto comb_found;                        
1600                qp = ptr (disksp, qrp);
1601                goto comb_loop;
1602 
1603 
1604 comb_found:
1605                if best_pos_comb ^= 34359738367 then         
1606                     qp = best_qp;                           
1607                else qp = best_neg_qp;
1608                qrp = rel (qp);
1609                return;
1610           end find_shortest_seek;
1611 ^L
1612 
1613 
1614 
1615 
1616 
1617 
1618 
1619 
1620 gotwork:
1621      entry;
1622 
1623 xfer_join:
1624           if ^quentry.used then                             
1625                call syserr (CRASH, "^a: Queuing error.", ME);
1626 
1627           chantab.qrp = rel (qp);                           
1628           chantab.erct = 0;                                 
1629           chantab.reconnect_announce_time = 0;              
1630 
1631           dev = quentry.dev;                                
1632 
1633           if quentry.type = TEST then do;
1634                idcwp = addr (chantab.rssdcw);               
1635                idcw.command = substr (quentry.coreadd, 19, 6);
1636                idcw.device = bit (dev);                     
1637 
1638 
1639 
1640                optp = addr (disktab.devtab (dev).opt_info (quentry.type));
1641                if bin (quentry.coreadd, 24) = 58 then
1642                     opt_info.seek_sum = opt_info.seek_sum + 1;
1643                                                             
1644                else opt_info.seek_count = opt_info.seek_count + 1;
1645                                                             
1646 
1647 
1648                call connect (idcwp);                        
1649           end;
1650 
1651           else do;                                          
1652                dcdcwp = addr (chantab.dcdcw);               
1653                dddcwp = addr (chantab.dddcw);               
1654                idcwp = addr (chantab.scdcw);                
1655 
1656                idcw.device = bit (dev);                     
1657 
1658                unspec (dcdcwp -> idcw) = "0"b;              
1659                dcdcwp -> idcw.code = IDCW;
1660                dcdcwp -> idcw.ext_ctl = "1"b;
1661                if write_map (quentry.type) then             
1662                     dcdcwp -> idcw.command = WRITE;
1663                else dcdcwp -> idcw.command = READ;
1664 
1665                dcdcwp -> idcw.ext = substr (quentry.coreadd, 1, length (idcw.ext));
1666                                                             
1667                dddcwp -> dcw.address = substr (quentry.coreadd, 7);
1668                                                             
1669                dcdcwp -> idcw.device = bit (dev);           
1670                                                             
1671 
1672 
1673                chantab.select_data.sector = quentry.sector; 
1674                                                             
1675                if idcw.command = seek_512 then do;          
1676                     if quentry.type = VTOC_READ | quentry.type = VTOC_WRITE then do;
1677                          dddcwp -> dcw.tally = bit (bin (192, 12));
1678                          chantab.select_data.limit = bit (bin (1, 12));
1679                     end;
1680                     else if quentry.type = PAGE_READ | quentry.type = PAGE_WRITE then do;
1681                          dddcwp -> dcw.tally = bit (bin (1024, 12));
1682                          chantab.select_data.limit = bit (bin (2, 12));
1683                     end;
1684                     else if sector_map (quentry.type) then do;
1685                          dddcwp -> dcw.tally = bit (bin ((512 * quentry.n_sectors), 12));
1686                          chantab.select_data.limit = bit (bin (quentry.n_sectors, 12));
1687                     end;
1688                end;
1689                else do;                                     
1690                     if sector_map (quentry.type) then do;   
1691                          dddcwp -> dcw.tally = bit (bin (64 * quentry.n_sectors, 12));
1692                                                             
1693                          chantab.select_data.limit = bit (bin (quentry.n_sectors, 12));
1694                                                             
1695                     end;
1696                     else do;                                
1697                          dddcwp -> dcw.tally = bit (bin (1024, 12));
1698                                                             
1699                          chantab.select_data.limit = bit (bin (16, 12));
1700                                                             
1701                     end;
1702                end;
1703 
1704                call connect (addr (chantab.scdcw));         
1705 
1706 
1707 
1708                optp = addr (disktab.devtab (dev).opt_info (quentry.type));
1709                cylinder = devtab.cylinder - quentry.cylinder;
1710                devtab.cylinder = quentry.cylinder;
1711 
1712 
1713 
1714 
1715 
1716 
1717                if cylinder > 0                              
1718                     then
1719                     devtab.forward = "0"b;
1720                else if cylinder < 0                         
1721                     then
1722                     devtab.forward = "1"b;
1723 
1724                opt_info.seek_sum = opt_info.seek_sum + abs (cylinder);
1725                opt_info.seek_count = opt_info.seek_count + 1;
1726           end;
1727      end getwork;
1728 ^L
1729 
1730 
1731 connect:
1732      procedure (listp);
1733 
1734 dcl       listp                  ptr parameter;
1735 dcl       1 ima                  aligned like io_manager_arg;
1736 
1737           ima.chx = chantab.chx;
1738           ima.pcw = ""b;
1739           ima.ptp = null ();
1740           ima.listp = listp;
1741           call io_manager$connect_abs (ima);                
1742                                                             
1743           chantab.connects = chantab.connects + 1;          
1744           chantab.active = "1"b;                            
1745           chantab.connect_time = clock ();                  
1746 
1747           disktab.dev_busy = disktab.dev_busy | dev_mask (pdi);
1748                                                             
1749 
1750           return;
1751 
1752 
1753      end connect;
1754 
1755 
1756 
1757 
1758 
1759 post:
1760      proc;
1761 
1762           if  io_type = TEST then do;
1763 
1764 
1765                post_sw = "0"b;
1766                return;
1767           end;
1768 
1769 
1770           if sect_sw then                                   
1771                if bootload_sw then
1772                     call bootload_disk_post (coreadd, errcd);
1773                else call vtoc_interrupt (coreadd, errcd);
1774           else                                              
1775                call page$done (coreadd, errcd);
1776 
1777           post_sw = "0"b;                                   
1778 
1779           return;
1780 
1781 
1782      end post;
1783 ^L
1784 
1785 
1786 queue_length_given_pvtx:
1787      entry (a_pvtx, a_queue_length);
1788 
1789           pvtep = addr (addr (pvt$array) -> pvt_array (a_pvtx));
1790                                                             
1791           pvtdip = addr (pvte.dim_info);                    
1792           sx = pvtdi.sx;                                    
1793 
1794           call setup;                                       
1795 
1796           dev = pvte.logical_area_number;                   
1797           pdi = disktab.devtab (dev).pdi;                   
1798           dp = addr (disktab.devtab (pdi));                 
1799 
1800           a_queue_length = devtab.wq.depth;                 
1801 
1802           return;
1803 ^L
1804 
1805 
1806 
1807 tune:
1808      entry (a_op, a_ptr, reason, ec);
1809 
1810 dcl       a_op                   char (*);                  
1811 dcl       a_ptr                  ptr;                       
1812 dcl       reason                 char (*) varying;          
1813 dcl       ec                     fixed bin (35);
1814 
1815 dcl       stagnate_time          fixed bin (35) based (cptr);
1816                                                             
1817 dcl       response               fixed bin (35);
1818 dcl       load                   fixed bin;
1819 dcl       cptr                   ptr;
1820 dcl       op                     char (16);
1821 
1822 %include disk_tune;
1823 %page;
1824           disksp = addr (disk_seg$);
1825           cptr = a_ptr;
1826           op = a_op;
1827 
1828           if op = STAGNATE_TIME then do;                    
1829                if stagnate_time > 360000000 | stagnate_time < 0 then do;
1830                     if stagnate_time < 0 then
1831                          reason = "stagnate time must be >= 0";
1832                     else reason = "stagname time must be <= 6 minutes";
1833                     ec = error_table_$bad_arg;
1834                     return;
1835                end;
1836                else disk_data.stagnate_time = a_ptr -> stagnate_time;
1837           end;
1838           else if op = SYS_TUNE then do;
1839                io_type = cptr -> sys_info_tune.type;
1840                if io_type < 0 | io_type > MAX_IO_TYPE then
1841                     goto bad_io_type;
1842 
1843                sysp = addr (disk_data.sys_info (io_type));
1844 
1845                if cptr -> sys_info_tune.map > MAX_IO_TYPE then
1846                     goto bad_map_type;
1847 
1848 
1849 
1850                if cptr -> sys_info_tune.map >= 0 then
1851                     sys_info.depth_map = rel (addr (disk_data.sys_info (cptr -> sys_info_tune.map)));
1852 
1853 
1854 
1855                if cptr -> sys_info_tune.max_depth > 0 then
1856                     sys_info.max_depth = float (cptr -> sys_info_tune.max_depth);
1857           end;
1858           else if op = OPT_TUNE then do;
1859                io_type = cptr -> opt_info_tune.type;
1860                if io_type < 0 | io_type > MAX_IO_TYPE then
1861                     goto bad_io_type;
1862 
1863                do sx = 1 to disk_data.subsystems;
1864                     if cptr -> opt_info_tune.sub_sys = disk_data.array (sx).name then
1865                          goto tune_sub_sys;
1866                end;
1867                goto bad_io_sub_sys;
1868 
1869 tune_sub_sys:
1870                call setup;                                  
1871                dev = cptr -> opt_info_tune.dev;
1872                if dev < lbound (disktab.devtab, 1) | dev > hbound (disktab.devtab, 1) then
1873                     goto bad_io_dev;
1874 
1875                pdi = disktab.devtab (dev).pdi;              
1876                if pdi ^= dev then
1877                     goto bad_io_dev;
1878 
1879                response = cptr -> opt_info_tune.response;
1880                if response < 1 then
1881                     goto response_range;
1882                load = cptr -> opt_info_tune.load;
1883 
1884                optp = addr (disktab.devtab (pdi).opt_info (io_type));
1885                if load > 1 then do;
1886                     opt_info.slope = float (response - 1) / float (load - 1);
1887                     opt_info.intercept = float ((response * load) - 1) / float (load - 1);
1888                end;
1889                else do;
1890                     opt_info.slope = 0.0;
1891                     opt_info.intercept = float (response);
1892                end;
1893           end;
1894           else if op = RESET_SYS then do;
1895                do i = 0 to MAX_IO_TYPE;                     
1896                     disk_data.sys_info (i).depth = 0;
1897                end;
1898           end;
1899           else if op = RESET_MAX then do;
1900                disk_data.max_depth_reset_time = clock ();
1901                disk_data.free_q.max_depth = 0;
1902                do i = 1 to disk_data.subsystems;            
1903                     diskp = ptr (disksp, disk_data.array (i).offset);
1904                     disktab.wq.max_depth = 0;
1905                end;
1906           end;
1907           reason = "";
1908           ec = 0;
1909           return;
1910 
1911 bad_io_type:
1912           reason = "invalid I/O type";
1913           ec = error_table_$bad_arg;
1914           return;
1915 
1916 bad_map_type:
1917           reason = "invalid map I/O type";
1918           ec = error_table_$bad_arg;
1919           return;
1920 
1921 bad_io_sub_sys:
1922           reason = "unknown subsystem";
1923           ec = error_table_$bad_arg;
1924           return;
1925 
1926 bad_io_dev:
1927           reason = "invalid device number";
1928           ec = error_table_$bad_arg;
1929           return;
1930 
1931 response_range:
1932           reason = "response value must be >= 1";
1933           ec = error_table_$bad_arg;
1934           return;
1935 ^L
1936 
1937 
1938 setup:
1939      proc;
1940 
1941 
1942           disksp = addr (disk_seg$);                        
1943           pvt_arrayp = addr (pvt$array);                    
1944           diskp = ptr (disksp, disk_data.offset (sx));      
1945 
1946           return;
1947 
1948 
1949      end setup;
1950 
1951 
1952 
1953 
1954 
1955 disk_name:
1956      proc (both) returns (char (21) aligned);
1957 
1958 dcl       both                   bit (1) aligned;
1959 dcl       pic99                  pic "99";
1960 dcl       this_name              char (8);
1961 dcl       other_name             char (12);
1962 dcl       other_dev              fixed bin;
1963 
1964 
1965           if dev = pdi                                      
1966                then
1967                other_dev = disktab.devtab (pdi).buddy;
1968           else other_dev = pdi;
1969 
1970           this_name = disk_data.name (sx) || "_" || convert (pic99, dev);
1971           if other_dev = 0 then
1972                other_name = "";
1973           else other_name = " and " || disk_data.name (sx) || "_" || convert (pic99, other_dev);
1974 
1975           if both                                           
1976                then
1977                return (this_name || other_name);
1978           else return (this_name);
1979 
1980 
1981      end disk_name;
1982 ^L
1983 
1984 
1985 
1986 lock:
1987      proc (lmp);
1988 
1989 dcl       1 dlm                  like disk_lock_meters based (lmp) aligned,
1990                                                             
1991           lmp                    ptr;
1992 
1993 
1994           dlm.count = dlm.count + 1;                        
1995           if ^stacq (disktab.lock, pds$processid, UNLOCK) then do;
1996                                                             
1997                call lock_meter_start (lmp);
1998                do while (^stacq (disktab.lock, pds$processid, UNLOCK));
1999                end;                                         
2000                call lock_meter_stop (lmp);
2001           end;
2002 
2003           return;
2004 
2005 
2006 unlock:
2007      entry;
2008 
2009           if ^stacq (disktab.lock, UNLOCK, disktab.lock) then
2010                ;                                            
2011 
2012           return;
2013 
2014 
2015      end lock;
2016 
2017 
2018 
2019 
2020 
2021 lock_meter_start:
2022      proc (lmp);
2023 
2024 dcl       1 dlm                  like disk_lock_meters based (lmp) aligned,
2025           lmp                    ptr;
2026 
2027 
2028           meter_start_time = clock ();                      
2029           dlm.waits = dlm.waits + 1;                        
2030 
2031           return;
2032 
2033 
2034 lock_meter_stop:
2035      entry (lmp);
2036 
2037           dlm.wait_time = dlm.wait_time + (clock () - meter_start_time);
2038                                                             
2039           return;
2040 
2041 
2042      end lock_meter_start;
2043 ^L
2044 
2045 
2046 get_free_q:
2047      proc returns (bit (1) aligned);
2048 
2049 dcl       type                   fixed bin;
2050 
2051 
2052 
2053           do while (^stacq (disk_data.lock, pds$processid, UNLOCK));
2054           end;
2055 
2056           qrp = disk_data.free_q.head;                      
2057           if qrp then do;                                   
2058                qp = ptr (disksp, qrp);                      
2059                disk_data.free_q.head = quentry.next;        
2060 
2061 
2062 
2063                if disk_data.free_q.head = "0"b then
2064                     disk_data.free_q.tail = "0"b;
2065                else ptr (disksp, quentry.next) -> quentry.prev = "0"b;
2066 
2067 
2068 
2069                disk_data.free_q.sum = disk_data.free_q.sum + disk_data.free_q.depth;
2070                disk_data.free_q.depth = disk_data.free_q.depth + 1;
2071                if disk_data.free_q.depth > disk_data.free_q.max_depth then
2072                     disk_data.free_q.max_depth = disk_data.free_q.depth;
2073                disk_data.free_q.count = disk_data.free_q.count + 1;
2074 
2075                if ^stacq (disk_data.lock, UNLOCK, disk_data.lock) then
2076                     ;                                       
2077                return (SUCCESS);
2078           end;
2079           else do;                                          
2080                if ^stacq (disk_data.lock, UNLOCK, disk_data.lock) then
2081                     ;                                       
2082                return (FAILURE);
2083           end;
2084 ^L
2085 
2086 
2087 add_free_q:
2088      entry;
2089 
2090           quentry.used = "0"b;                              
2091 
2092 
2093 
2094           do while (^stacq (disk_data.lock, pds$processid, UNLOCK));
2095           end;                                              
2096 
2097 
2098 
2099           if disk_data.free_q.tail ^= "0"b then
2100                ptr (disksp, disk_data.free_q.tail) -> quentry.next = qrp;
2101           else disk_data.free_q.head = qrp;
2102 
2103           quentry.prev = disk_data.free_q.tail;             
2104           disk_data.free_q.tail = qrp;                      
2105           quentry.next = "0"b;                              
2106 
2107 
2108 
2109           disk_data.free_q.depth = disk_data.free_q.depth - 1;
2110 
2111           if ^stacq (disk_data.lock, UNLOCK, disk_data.lock) then
2112                ;                                            
2113           return;
2114 ^L
2115 
2116 
2117 add_wq:
2118      entry;
2119 
2120 
2121 
2122 
2123           disktab.dev_queued = disktab.dev_queued | dev_mask (pdi);
2124           if devtab.wq.tail ^= "0"b then
2125                ptr (disksp, devtab.wq.tail) -> quentry.next = qrp;
2126           else devtab.wq.head = qrp;
2127 
2128           quentry.prev = devtab.wq.tail;
2129           quentry.next = "0"b;
2130           devtab.wq.tail = qrp;
2131 
2132 
2133 
2134           devtab.wq.sum = devtab.wq.sum + devtab.wq.depth;
2135           devtab.wq.depth = devtab.wq.depth + 1;
2136           if devtab.wq.depth > devtab.wq.max_depth then
2137                devtab.wq.max_depth = devtab.wq.depth;
2138           devtab.wq.count = devtab.wq.count + 1;
2139 
2140 
2141 
2142 
2143           type = quentry.type;
2144           sysp = addr (disk_data.sys_info (type));
2145           do while (^stacq (disk_data.lock, pds$processid, UNLOCK));
2146           end;
2147           ptr (disksp, sys_info.depth_map) -> sys_info.depth = ptr (disksp, sys_info.depth_map) -> sys_info.depth + 1.0;
2148           optp = addr (devtab.opt_info (type));
2149           opt_info.depth = opt_info.depth + 1;
2150 
2151 
2152 
2153 wq_common:
2154           sys_info.fraction =
2155                (sys_info.max_depth - ptr (disksp, sys_info.depth_map) -> sys_info.depth) / sys_info.max_depth;
2156           if sys_info.fraction < 0.0 then
2157                sys_info.fraction = 0.0;
2158           if ^stacq (disk_data.lock, UNLOCK, disk_data.lock) then
2159                ;                                            
2160 
2161 
2162 
2163 
2164           opt_info.multiplier = (opt_info.intercept - float (opt_info.depth) * opt_info.slope) * sys_info.fraction;
2165           if opt_info.multiplier < 1.0 then
2166                opt_info.multiplier = 1.0;                   
2167           return;
2168 ^L
2169 
2170 
2171 del_q:
2172      entry;
2173 
2174 
2175 
2176           if quentry.prev = "0"b then                       
2177                devtab.wq.head = quentry.next;
2178           else ptr (disksp, quentry.prev) -> quentry.next = quentry.next;
2179 
2180           if quentry.next = "0"b then                       
2181                devtab.wq.tail = quentry.prev;
2182           else ptr (disksp, quentry.next) -> quentry.prev = quentry.prev;
2183 
2184 
2185 
2186           devtab.wq.depth = devtab.wq.depth - 1;
2187           if devtab.wq.depth <= 0 then
2188                disktab.dev_queued = disktab.dev_queued & ^dev_mask (pdi);
2189 
2190 
2191 
2192           type = quentry.type;
2193           sysp = addr (disk_data.sys_info (type));
2194           do while (^stacq (disk_data.lock, pds$processid, UNLOCK));
2195           end;                                              
2196 
2197 
2198 
2199           ptr (disksp, sys_info.depth_map) -> sys_info.depth =
2200                max (0.0, ptr (disksp, sys_info.depth_map) -> sys_info.depth - 1.0);
2201 
2202           optp = addr (devtab.opt_info (type));
2203           opt_info.depth = opt_info.depth - 1;
2204           go to wq_common;                                  
2205 
2206      end get_free_q;
2207 ^L
2208 
2209 
2210 
2211 set_pvte_inop:
2212      proc (setting);
2213 
2214 dcl       setting                bit (1) aligned;
2215 
2216 
2217 
2218 
2219           call set (addr (addr (pvt$array) -> pvt_array (devtab.pvtx)));
2220                                                             
2221           if devtab.buddy ^= 0                              
2222                then
2223                call set (addr (addr (pvt$array) -> pvt_array (disktab.devtab (devtab.buddy).pvtx)));
2224 
2225 set:
2226           proc (pvte_ptr);
2227 
2228 dcl       pvte_ptr               ptr;
2229 
2230 
2231                if pvte_ptr -> pvte.device_inoperative & ^setting then do;
2232                     pvte_ptr -> pvte.device_inoperative = "0"b;
2233                     call pxss$notify (page_fault$disk_offline_event);
2234                end;
2235                else pvte_ptr -> pvte.device_inoperative = setting;
2236 
2237                return;
2238 
2239 
2240           end set;
2241 
2242      end set_pvte_inop;
2243 ^L
2244 %include device_error;
2245 %page;
2246 %include disk_error_interp;
2247 %page;
2248 %include dskdcl;
2249 %page;
2250 %include fs_dev_types;
2251 %page;
2252 %include io_manager_dcls;
2253 %page;
2254 %include io_special_status;
2255 %page;
2256 %include io_status_entry;
2257 %page;
2258 %include io_syserr_msg;
2259 %page;
2260 %include iom_dcw;
2261 %page;
2262 %include iom_pcw;
2263 %page;
2264 %include pvte;
2265 %page;
2266 %include syserr_binary_def;
2267 %page;
2268 %include syserr_constants;
2269 ^L
2270 
2271 
2272 
2273 
2274 
2275 
2276 
2277 
2278 
2279 
2280 
2281 
2282 
2283 
2284 
2285 
2286 
2287 
2288 
2289 
2290 
2291 
2292 
2293 
2294 
2295 
2296 
2297 
2298 
2299 
2300 
2301 
2302 
2303 
2304 
2305 
2306 
2307 
2308 
2309 
2310 
2311 
2312 
2313 
2314 
2315 
2316 
2317 
2318 
2319 
2320 
2321 
2322 
2323 
2324 
2325 
2326 
2327 
2328 
2329 
2330 
2331 
2332 
2333 
2334 
2335 
2336 
2337 
2338 
2339 
2340 
2341 
2342 
2343 
2344 
2345 
2346 
2347 
2348 
2349 
2350 
2351 
2352 
2353 
2354 
2355 
2356 
2357 
2358 
2359 
2360 
2361 Note
2362 
2363 
2364 
2365 
2366 
2367 
2368 
2369 
2370 
2371 
2372 
2373 
2374 
2375 
2376 
2377 
2378 
2379 
2380 
2381 
2382 
2383 
2384 
2385 
2386 
2387 
2388 
2389 
2390 
2391 Note
2392 
2393 
2394 
2395 
2396 
2397 
2398 
2399 
2400 
2401 
2402 
2403 
2404 
2405 
2406 
2407 
2408 
2409 
2410 
2411 
2412 
2413 
2414 
2415 
2416 
2417 
2418 
2419 
2420 
2421 
2422 
2423 
2424 
2425 
2426 
2427 
2428 
2429 
2430 
2431 
2432 
2433 
2434 
2435 
2436 
2437 
2438 
2439 
2440 
2441 
2442      end disk_control;