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( byte0 && nok%PGSIZE==0) || wc==0) ) { if( hpx>0 ) byte += nok-PGSIZE; while( 0<=BYTE BYTEb_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 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.