$CONTROL MAP,CODE,USLINIT                                               00010000
<<pfail - module 30>>                                                   00012000
<< hp32002c mpe source c.00.00 >>                                       00014000
$copyright     "(C) COPYRIGHT HEWLETT-PACKARD CO. 1980. ",            & 00016000
$     "THIS PROGRAM MAY BE USED WITH ONE COMPUTER SYSTEM AT A ",      & 00018000
$     "TIME AND SHALL NOT OTHERWISE BE RECORDED, TRANSMITTED OR ",    & 00020000
$     "STORED IN A RETRIEVAL SYSTEM.  COPYING OR OTHER REPRODUCTION ",& 00022000
$     "OF THIS PROGRAM EXCEPT FOR ARCHIVAL PURPOSES IS PROHIBITED ",  & 00024000
$     "WITHOUT THE PRIOR WRITTEN CONSENT OF HEWLETT-PACKARD COMPANY."   00026000
$control uncallable,privileged,main=pfail                               00028000
$thirty                                                                 00030000
$title "POWERFAIL RESTART/RECOVERY PROCESS"                             00032000
begin                                                                   00034000
                                                                        00036000
equate                                                                  00038000
   powerfail   = %72, << sysdb index >>                                 00040000
   pfailure    = 65,   << opcode to tell driver pfailed >>     <<00144>>00042000
   sysdb       = %1000,                                                 00044000
   syslpdt     = %10,                                                   00046000
   dinil       = 7,                                            <<00.04>>00048000
   dioqp       = 2,   << dit index to ioq pointer >>                    00050000
   ddltp       = 4,   << dit index to dvr link table ptr >>             00052000
   dmntr       = 1,   << dlt index to monitor plabel >>                 00054000
   junkwait    = -%20,                                                  00056000
   junk'iowait = -%120,                                                 00058000
   consldev    = %74, << sysdb index >>                                 00060000
   qi          = 5;                                                     00062000
                                                                        00064000
define                                                                  00066000
   qpfails     = (11:1)#,  << pfail to be indicated by attachio<<00144>>00068000
   abort       = (0:1)#,  << abort bit of ioq >>                        00070000
   abs         = absolute#,                                             00072000
   asmb        = assemble#,                                             00074000
   dircstate   = (0:2)#,   << device recognition state in lpdt >>       00076000
   disable     = assemble(sed 0)#,                                      00078000
   enable      = assemble(sed 1)#,                                      00080000
   iak         = (8:1)#,  << interrupt acknowledge bit of dit >>        00082000
   maxentry    = (0:8)#,  << # of entries in lpdt >>                    00084000
   pdisable    = asmb(psdb)#,                                           00086000
   penable     = asmb(pseb)#,                                           00088000
   pf          = abs(sysdb+powerfail)#,                                 00090000
   pfail       = (11:1)#, << pfail bit of ioq >>                        00092000
   request     = (3:1)#; << request flag of dit dflags >>               00094000
                                                                        00096000
integer                                                                 00098000
   sysup       = db+%73,                                                00100000
   sysconsole  = db+consldev;                                           00102000
                                                                        00104000
integer pointer                                                         00106000
   lpdt        = db+syslpdt,                                            00108000
   ps0         = s-0,                                                   00110000
   ps1         = s-1;                                                   00112000
                                                                        00114000
double pointer                                                          00116000
   lpdtd       = lpdt;                                                  00118000
                                                                        00120000
array                                                                   00122000
   pfmsg(0:7)  := %6412,"**POWER FAIL**";                               00124000
                                                                        00126000
integer array                                                           00128000
   ioqx(0:255) := 256(0);                                               00130000
$page                                                                   00132000
double procedure attachio(ldev,qmisc,dstx,addr,func,cnt,p1,p2,flags);   00134000
value ldev,qmisc,dstx,addr,func,cnt,p1,p2,flags;                        00136000
integer ldev,qmisc,dstx,addr,func,cnt,p1,p2,flags;                      00138000
option external;                                                        00140000
                                                                        00142000
procedure awakeio(ditp,flags);                                          00144000
value ditp,flags;                                                       00146000
pointer ditp;                                                           00148000
logical flags;                                                          00150000
option external;                                                        00152000
                                                                        00154000
procedure checkldev(dev);                                               00156000
value dev;                                                              00158000
integer dev;                                                            00160000
option external;                                                        00162000
                                                                        00164000
procedure dsetcontrol(op,ditp);                                         00166000
value op,ditp;                                                          00168000
integer op;                                                             00170000
pointer ditp;                                                           00172000
option external;                                                        00174000
                                                                        00176000
procedure log7;                                                         00178000
option external;                                                        00180000
                                                                        00182000
double procedure iostatus(ioqx);                                        00184000
value ioqx;                                                             00186000
integer ioqx;                                                           00188000
option external;                                                        00190000
                                                                        00192000
procedure help;                                                         00194000
option external;                                                        00196000
                                                                        00198000
procedure resetdb(a);                                                   00200000
value a;                                                                00202000
integer a;                                                              00204000
option external;                                                        00206000
                                                                        00208000
procedure setsysdb;                                                     00210000
option external;                                                        00212000
                                                                        00214000
procedure terminit(ditp);                                               00216000
value ditp;                                                             00218000
pointer ditp;                                                           00220000
option external;                                                        00222000
                                                                        00224000
procedure wait(a,b);                                                    00226000
value a,b;                                                              00228000
integer a,b;                                                            00230000
option external;                                                        00232000
                                                               <<02062>>00234000
logical procedure exchangedb(inx);                             <<02062>>00236000
    value   inx;                                               <<02062>>00238000
    integer  inx;                                              <<02062>>00240000
    option external;                                           <<02062>>00242000
                                                                        00244000
$page                                                                   00246000
procedure powerup;                                                      00248000
begin                                                                   00250000
integer i,j,k,l,x=x;                                                    00252000
integer device;                                                <<02062>>00254000
double dsave;                                                           00256000
integer pointer ditp = dsave;                                           00258000
integer array ldt(*) = db + 0;                                 <<02062>>00260000
logical lflags = dsave+1,new := true;                                   00262000
logical qpfail;   << tell driver of pfail via attachio >>      <<00144>>00264000
equate  ldtdst = %16,                                          <<02062>>00266000
   inp'dev     = %21,          <<inp device number>>           <<02062>>00268000
   wordct      = 5;                                            <<02062>>00270000
define drstate = (0:2)#,               <<device state>>        <<02062>>00272000
   dev'type    = (10:6)#;       <<device type>>                <<02062>>00274000
                                                                        00276000
                                                                        00278000
restart:                                                                00280000
   setsysdb;                                                            00282000
   pf := 4; << set powerfail indicator to recovery >>                   00284000
   enable;                                                              00286000
   i := 1;                                                              00288000
   do                                                                   00290000
   begin << examine all devices to determine disposition >>             00292000
      dsave := lpdtd(i);                                                00294000
      resetdb(-1);                                             <<02062>>00296000
      exchangedb(ldtdst);                                      <<02062>>00298000
      device := ldt(i*wordct+2);                               <<02062>>00300000
      exchangedb(0);                                           <<02062>>00302000
      setsysdb;         <<back to sys glob>>                   <<02062>>00304000
      tos := @ditp;                                            <<00.04>>00306000
      if > and (device.dev'type <> inp'dev or                  <<02062>>00308000
                lflags.drstate <> 0) then                      <<02062>>00310000
    << the device is an inp (that is owned) or not an inp->>   <<02062>>00312000
    << so initialize the devices*a fix for cs devices     >>   <<02062>>00314000
      begin                                                    <<00.05>>00316000
                                                               <<00.05>>00318000
      tos := ditp(ddltp); << dlt ptr >>                        <<00.04>>00320000
      qpfail := ps0.qpfails; << flag to tell driver via attachi<<00144>>00322000
      tos := ps0(dinil); << initialization plabel >>           <<00.04>>00324000
      delb;                                                    <<00.04>>00326000
      if < then asmb(pcal 0) else ddel;                        <<00.04>>00328000
      checkldev(i);                                                     00330000
      if = and nocarry then                                             00332000
      if qpfail then attachio(i,0,0,0,pfailure,0,0,0,%13) else <<00144>>00334000
      begin << non disc sio device >>                                   00336000
abortsio:                                                               00338000
         disable;                                                       00340000
         tos := ditp(dioqp);                                            00342000
         if <> then                                                     00344000
         begin << ioq attached, abort the i/o >>                        00346000
            tos := ps0;                                                 00348000
            tos.abort := 1;                                             00350000
            tos.pfail := 1;                                             00352000
            ps1 := tos;                                                 00354000
            tos := ditp; << get flags word of dit >>                    00356000
            tos.iak := 1;                                               00358000
            tos.request := 1;                                           00360000
            ditp := tos;                                                00362000
            pdisable;                                                   00364000
            enable;                                                     00366000
            awakeio(ditp,0); << have driver do the abort >>             00368000
            penable;                                                    00370000
         end;                                                           00372000
         enable;                                                        00374000
         del;                                                           00376000
      end;                                                              00378000
                                                                        00380000
      end else del;                                            <<00.05>>00382000
      if pf <> 4 then go restart;                                       00384000
   end until (i:=i+1) > lpdt.maxentry;                                  00386000
   abs(abs(qi)-12) := 0; << reset pfail flag so users will run >>       00388000
   resetdb(-1);                                                         00390000
   tos := new;                                                          00392000
   tos := 7;                                                            00394000
   log7; << issue log record to record powerfail >>                     00396000
   setsysdb;                                                            00398000
   if new then                                                          00400000
   begin << new powerfail, send messages to terminals >>                00402000
      j := 0;                                                           00404000
      k := -1;                                                          00406000
      new := false;                                                     00408000
   end;                                                                 00410000
   while (j := j + 1) <= lpdt.maxentry do                               00412000
   begin << send powerfail message to all active terminals >>           00414000
      checkldev(j);                                                     00416000
      if > then                                                         00418000
      begin << device is a terminal >>                                  00420000
         dsave := lpdtd(j);                                             00422000
         if lflags.dircstate <> 0 then                                  00424000
         begin << send pfail msg to terminal >>                         00426000
            l := (if j = sysconsole then 1 else 8);                     00428000
            resetdb(-1);                                                00430000
            tos := attachio(j,0,0,@pfmsg,1,l,0,0,%406);                 00432000
            assemble(del,test);                                         00434000
            if <> then ioqx(k:=k+1) := tos else del;                    00436000
            << forget request if out of ioq's >>                        00438000
            setsysdb;                                                   00440000
         end;                                                           00442000
      end;                                                              00444000
      if pf <> 4 then go restart;                                       00446000
   end;                                                                 00448000
   sysup := 1;                                                          00450000
   resetdb(-1);                                                         00452000
checkagain:  << now allow all the i/o to complete >>                    00454000
   for x := 0 until k do                                                00456000
   if ioqx(x) <> 0 then                                                 00458000
   begin << check for completion >>                                     00460000
      iostatus(ioqx(x));                                                00462000
      if <= then ioqx(x) := 0; << all done, zero entry >>               00464000
   end;                                                                 00466000
   tos := ioqx(0); << see if all i/o is complete >>                     00468000
   while (x:=x+1) <= k do tos := tos lor logical(ioqx(x));              00470000
   asmb(test,del);                                                      00472000
   if <> then                                                           00474000
   begin << not all done yet >>                                         00476000
      wait( junk'iowait,0);                                             00478000
      if pf <> 4 then go restart;                                       00480000
      go checkagain;                                                    00482000
   end;                                                                 00484000
   if pf <> 4 then go to restart;                                       00486000
   pf := 0;                                                             00488000
   new := true;                                                         00490000
waitsomemore:                                                           00492000
   wait(junkwait,0);                                                    00494000
   if pf <> 0 then go restart;                                          00496000
   go waitsomemore;                                                     00498000
   help;                                                                00500000
end;                                                                    00502000
   powerup;                                                             00504000
end.                                                                    00506000
