Aucbvax.3281
net.2bsd-bugs
utzoo!decvax!ucbvax!william
Wed Sep 23 16:39:32 1981
Re:  MENLO_ECC
The released code is old and know not to work. It is part of a shitload of
old code that got edited in at the last momement for reasons not made clear
to me (I think someone got his diff mixed up). Here is code known to work
on a RP06 RH70 sys.



##### hpecc (hp.c) ######
hpecc(rp,bp,dp)
   register struct device *rp;
   register struct buf *bp;
   struct buf *dp;
{
# define exadr(x,y) (((long)(x)<<16)|(UNSIGNED)(Y)) BB,ADDR; ~(~0L<<(X)) # *NOK /* PAGE LAST XFERRED. *UBP; BE THE DEFINE INT *WHICH BN; TO CN,TN,SN; WRONG; ERROR LONG DISK BIT,BYTE,NOK,HPX,WC; WC="rp-" BITFLD(X) UBADR_T #BYTES */ INCLUDING IN IS OCMD; ASSUMED>hpwc;
   nok = (wc+bp->b_bcount/NBPW)*NBPW;
   hpx = nok/PGSIZE;
printf("%D ",bp->b_blkno+hpx);
prdev("ECC",bp->b_dev);
   wrong = rp->hpec2&(int)bitfld(11);
   if( wrong==0 )
   {
       rp->hpof = FMT22;
       rp->hpcs1.w |= IE;
       return 0;
   }
   ocmd = (rp->hpcs1.w&~DRY)|IE|GO;

   /*
    *compute the byte/bit position of the err
    *within the last disk page xferred.
    */
   byte = rp->hpec1-1;
   bit = byte&(int)bitfld(3);
   byte >>= 3;
   /*correct while possible bits remain of mask*/
   bb = exadr(bp->b_xmem,bp->b_un.b_addr);
   if( byte<PGSIZE ((HPX &&>0 && nok%PGSIZE==0) || wc==0) )
   {
       if( hpx>0 )
           byte += nok-PGSIZE;
       while( 0<=BYTE BYTE<BP- &&>b_bcount && (wrong<<=BIT)!=0 ) { ADDR="bb+byte;" BP- IF(>b_flags&B_PHYS && bp->b_flags&B_MAP )
           {
               /*simulate ubmap if twas unibus xfer*/
               /*untested*/
printf("RAW XFER\n");
               ubp = UBMAP+((addr>>13)&(int)bitfld(5));
               addr = exadr(ubp->ub_hi,ubp->ub_lo)
                   +(addr&bitfld(13));
           }
printf("MEMADR==%D\n",addr);
           putmemc(addr,getmemc(addr)^(int)wrong);
           byte++;
           bit = -8;
       }
   }

   /*getmemc() changes pri.  might be a race.*/
   spl5();
   dp->b_active++;
   if( wc==0 )
       return 0;

   /*have to continue the transfer*/
   /*cross fingers*/
printf("RESTARTING...\n");
   nok = hpx*PGSIZE;
/*rp->hpcs1.w=DCLR|GO;*/
   rp->hpcs2.w = dkunit(bp);
   rp->hpcs1.w = TRE|DCLR|GO/*~IE*/;

   bn = dkblock(bp);
   cn = bp->b_cylin-bn/(NSECT*NTRAC)/*.cyloff*/;
   bn += hpx;
   addr = bb+nok;

   cn += bn/(NSECT*NTRAC);
   sn = bn%(NSECT*NTRAC);
   tn = sn/NSECT;
   sn %= NSECT;

   rp->hpdc = cn;
   rp->hpda = (tn<<8)+SN; RP->hpwc = nok/NBPW-bp->b_bcount/NBPW;
   rp->hpba = (int)addr;
   if( cputype==70 )
       rp->hpbae = (int)(addr>>16);
/*rp->hpcs1.w=RCOM|IE|GO;*/
   rp->hpcs1.w = ocmd;
   return 1;
}
#########################

The RAW code is seldom used, because there are no bad swap areas
I have no idea if it works on single 512 reads, it should. This
routine works correcting about 8 times a day one bad spot on one
RP06. There is one change from the working version here; menlo70
calls some of their hps np's....


       Bill.

-----------------------------------------------------------------
gopher://quux.org/ conversion by John Goerzen <[email protected]>
of http://communication.ucsd.edu/A-News/


This Usenet Oldnews Archive
article may be copied and distributed freely, provided:

1. There is no money collected for the text(s) of the articles.

2. The following notice remains appended to each copy:

The Usenet Oldnews Archive: Compilation Copyright (C) 1981, 1996
Bruce Jones, Henry Spencer, David Wiseman.