From 71da8eadad55fb9183bccbdda783701a80573b08 Mon Sep 17 00:00:00 2001 From: Mike Karels Date: Fri, 23 Sep 1983 17:07:35 -0800 Subject: [PATCH] ghg's severe burnin format SCCS-vsn: sys/vax/stand/format.c 6.3 SCCS-vsn: sys/stand.att/saio.h 6.2 SCCS-vsn: sys/vax/stand/hp.c 6.2 SCCS-vsn: sys/stand.att/sys.c 6.2 --- usr/src/sys/stand.att/saio.h | 5 +- usr/src/sys/stand.att/sys.c | 10 +- usr/src/sys/vax/stand/format.c | 252 +++++++++++++++++++++++---------- usr/src/sys/vax/stand/hp.c | 87 +++++++----- 4 files changed, 242 insertions(+), 112 deletions(-) diff --git a/usr/src/sys/stand.att/saio.h b/usr/src/sys/stand.att/saio.h index 18667ac3ea..af054349ec 100644 --- a/usr/src/sys/stand.att/saio.h +++ b/usr/src/sys/stand.att/saio.h @@ -1,4 +1,4 @@ -/* saio.h 6.1 %G% */ +/* saio.h 6.2 %G% */ /* * Header file for standalone package @@ -38,6 +38,7 @@ struct iob { #define F_NBSF 0x10 /* no bad sector forwarding */ #define F_ECCLM 0x20 /* limit # of bits in ecc correction */ #define F_SSI 0x40 /* set skip sector inhibit */ +#define F_SEVRE 0x80 /* Severe burnin (no retries, no ECC) */ /* io types */ #define F_RDDATA 0x0100 /* read data */ #define F_WRDATA 0x0200 /* write data */ @@ -115,6 +116,8 @@ extern int errno; /* just like unix */ #define SAIONOSSI (('d'<<8)|10) /* inhibit skip sector handling */ #define SAIOSSDEV (('d'<<8)|11) /* is device skip sector type? */ #define SAIODEBUG (('d'<<8)|12) /* enable/disable debugging */ +#define SAIOSEVRE (('d'<<8)|13) /* severe burnin, no ECC, no retries */ +#define SAIONSEVRE (('d'<<8)|14) /* clear severe burnin */ /* codes for sector header word 1 */ #define HDR1_FMT22 0x1000 /* standard 16 bit format */ diff --git a/usr/src/sys/stand.att/sys.c b/usr/src/sys/stand.att/sys.c index 1fb6dd293c..6ac73c4c8f 100644 --- a/usr/src/sys/stand.att/sys.c +++ b/usr/src/sys/stand.att/sys.c @@ -1,4 +1,4 @@ -/* sys.c 6.1 83/07/29 */ +/* sys.c 6.2 83/09/23 */ #include "../h/param.h" #include "../h/inode.h" @@ -568,6 +568,14 @@ ioctl(fdesc, cmd, arg) file->i_flgs &= ~F_ECCLM; break; + case SAIOSEVRE: + file->i_flgs |= F_SEVRE; + break; + + case SAIONSEVRE: + file->i_flgs &= ~F_SEVRE; + break; + default: error = devioctl(file, cmd, arg); break; diff --git a/usr/src/sys/vax/stand/format.c b/usr/src/sys/vax/stand/format.c index b5e7598d6a..58e667b620 100644 --- a/usr/src/sys/vax/stand/format.c +++ b/usr/src/sys/vax/stand/format.c @@ -1,4 +1,5 @@ -/* format.c 6.2 83/09/18 */ +/* format.c 6.3 83/09/23 */ + /* * Standalone program to do media checking @@ -53,23 +54,47 @@ errornames[NERRORS] = { int errors[NERRORS]; /* histogram of errors */ int pattern; +/* + * Purdue/EE severe burnin patterns. + */ +unsigned short ppat[] = { +0031463,0070707,0133333,0155555,0161616,0143434, +0107070,0016161,0034343,0044444,0022222,0111111,0125252, 052525, +0125252,0125252,0125252,0125252,0125252,0125252,0125252,0125252, +#ifndef SHORTPASS +0125252,0125252,0125252,0125252,0125252,0125252,0125252,0125252, + 052525, 052525, 052525, 052525, 052525, 052525, 052525, 052525, +#endif + 052525, 052525, 052525, 052525, 052525, 052525, 052525, 052525 + }; + +#define NPT (sizeof (ppat) / sizeof (short)) +int npat; /* subscript to ppat[] */ +int severe; /* nz if running "severe" burnin */ +int nbads; /* subscript for bads */ +long bads[MAXBADDESC]; /* Bad blocks accumulated */ + char *malloc(); +int qcompar(); char *prompt(); extern int end; main() { register int sector, sn; - int lastsector, tracksize; + int lastsector, tracksize, rtracksize; int unit, fd, resid, i, trk, cyl, debug; struct st st; struct sector *bp, *cbp; + char *rbp, *rcbp; + int pass, maxpass; char *cp; printf("Disk format/check utility\n\n"); again: - cp = prompt("Enable debugging (1=bse, 2=ecc, 3=bse+ecc)? "); + nbads = 0; + cp = prompt("Enable debugging (0=none, 1=bse, 2=ecc, 3=bse+ecc)? "); debug = atoi(cp); if (debug < 0) debug = 0; @@ -82,90 +107,123 @@ again: if (getpattern()) goto again; printf("Start formatting...make sure the drive is online\n"); + if (severe) + ioctl(fd, SAIOSEVRE, (char *) 0); ioctl(fd, SAIONOBAD, (char *)0); ioctl(fd, SAIOECCLIM, (char *)0); ioctl(fd, SAIODEBUG, (char *)debug); if (SSDEV) { + if (severe) { + printf("Severe burnin doesn't work with RM80 yet\n"); + exit(1); + } ioctl(fd, SAIOSSI, (char *)0); /* set skip sector inhibit */ st.nsect++; st.nspc += st.ntrak; } tracksize = sizeof (struct sector) * st.nsect; + rtracksize = SECTSIZ * st.nsect; bp = (struct sector *)malloc(tracksize); - bufinit(bp, tracksize); - /* - * Begin check, for each track, - * - * 1) Write header and test pattern. - * 2) Write check header and data. - */ - lastsector = st.nspc * st.ncyl; - for (sector = 0; sector < lastsector; sector += st.nsect) { - cyl = sector / st.nspc; - trk = (sector % st.nspc) / st.nsect; - for (i = 0; i < st.nsect; i++) { - bp[i].header1 = - (u_short) cyl | HDR1_FMT22 | HDR1_OKSCT; - bp[i].header2 = ((u_short)trk << 8) + i; - } - if (sector && (sector % (st.nspc * 10)) == 0) - printf("cylinder %d\n", cyl); + rbp = malloc(rtracksize); + if (severe) { + npat = 0; + maxpass = NPT; + } else + maxpass = 1; + for (pass = 0; pass < maxpass; pass++) { + if (severe) + printf("Begin pass %d\n", pass); + bufinit(bp, tracksize); + if (severe) + npat++; /* - * Try and write the headers and data patterns into - * each sector in the track. Continue until such - * we're done, or until there's less than a sector's - * worth of data to transfer. + * Begin check, for each track, * - * The lseek call is necessary because of - * the odd sector size (516 bytes) + * 1) Write header and test pattern. + * 2) Read data. Hardware checks header and data ECC. + * Read data (esp on Eagles) is much faster when write check. */ - for (resid = tracksize, cbp = bp, sn = sector;;) { - int cc; - - lseek(fd, sn * SECTSIZ, 0); - ioctl(fd, SAIOHDR, (char *)0); - cc = write(fd, cbp, resid); - if (cc == resid) - break; + lastsector = st.nspc * st.ncyl; + for (sector = 0; sector < lastsector; sector += st.nsect) { + cyl = sector / st.nspc; + trk = (sector % st.nspc) / st.nsect; + for (i = 0; i < st.nsect; i++) { + bp[i].header1 = + (u_short) cyl | HDR1_FMT22 | HDR1_OKSCT; + bp[i].header2 = ((u_short)trk << 8) + i; + } + if (sector && (sector % (st.nspc * 100)) == 0) + printf("cylinder %d\n", cyl); /* - * Don't record errors during write, - * all errors will be found during - * writecheck performed below. + * Try and write the headers and data patterns into + * each sector in the track. Continue until such + * we're done, or until there's less than a sector's + * worth of data to transfer. + * + * The lseek call is necessary because of + * the odd sector size (516 bytes) */ - sn = iob[fd - 3].i_errblk; - cbp += sn - sector; - resid -= (sn - sector) * sizeof (struct sector); - if (resid < sizeof (struct sector)) - break; - } - /* - * Write check headers and test patterns. - * Retry remainder of track on error until - * we're done, or until there's less than a - * sector to verify. - */ - for (resid = tracksize, cbp = bp, sn = sector;;) { - int cc; - - lseek(fd, sn * SECTSIZ, 0); - ioctl(fd, SAIOHCHECK, (char *)0); - cc = read(fd, cbp, resid); - if (cc == resid) - break; - sn = iob[fd-3].i_errblk; - printf("sector %d, write check error\n", sn); - recorderror(fd, sn, &st); - /* advance past bad sector */ - sn++; - cbp += sn - sector; - resid -= (sn - sector) * sizeof (struct sector); - if (resid < sizeof (struct sector)) - break; + for (resid = tracksize, cbp = bp, sn = sector;;) { + int cc; + + lseek(fd, sn * SECTSIZ, 0); + ioctl(fd, SAIOHDR, (char *)0); + cc = write(fd, cbp, resid); + if (cc == resid) + break; + /* + * Don't record errors during write, + * all errors will be found during + * writecheck performed below. + */ + sn = iob[fd - 3].i_errblk; + cbp += sn - sector; + resid -= (sn - sector) * sizeof (struct sector); + if (resid < sizeof (struct sector)) + break; + } + /* + * Read test patterns. + * Retry remainder of track on error until + * we're done, or until there's less than a + * sector to verify. + */ + for (resid = rtracksize, rcbp = rbp, sn = sector;;) { + int cc; + + lseek(fd, sn * SECTSIZ, 0); + cc = read(fd, rcbp, resid); + if (cc == resid) + break; + sn = iob[fd-3].i_errblk; + printf("sector %d, read error\n", sn); + if (recorderror(fd, sn, &st) < 0 && pass > 0) + goto out; + /* advance past bad sector */ + sn++; + rcbp += sn - sector; + resid -= ((sn - sector) * SECTSIZ); + if (resid < SECTSIZ) + break; + } } } /* * Checking finished. */ +out: + if (severe && nbads) { + /* + * Sort bads and insert in bad block table. + */ + qsort(bads, nbads, sizeof (long), qcompar); + severe = 0; + for (i = 0; i < nbads; i++) { + errno = EECC; /* for now */ + recorderror(fd, bads[i], &st); + } + severe++; + } if (errors[FE_TOTAL] || errors[FE_SSE]) { printf("Errors:\n"); for (i = 0; i < NERRORS; i++) @@ -192,11 +250,27 @@ again: printf("Done\n"); ioctl(fd,SAIONOSSI,(char *)0); close(fd); +/* + if (severe) { + asm("halt"); + exit(0); + } +*/ #ifndef JUSTEXIT goto again; #endif } +qcompar(l1, l2) +register long *l1, *l2; +{ + if (*l1 < *l2) + return(-1); + if (*l1 == *l2) + return(0); + return(1); +} + /* * Write out the bad blocks. */ @@ -243,23 +317,39 @@ writebb(fd, nsects, dbad, st, sw) /* * Record an error, and if there's room, put * it in the appropriate bad sector table. + * + * If severe burnin store block in a list after making sure + * we have not already found it on a prev pass. */ recorderror(fd, bn, st) int fd, bn; register struct st *st; { int cn, tn, sn, strk; - + register i; + + + if (severe) { + for (i = 0; i < nbads; i++) + if (bads[i] == bn) + return(0); /* bn already flagged */ + if (nbads >= MAXBADDESC) { + printf("Bad sector table full, burnin terminating\n"); + return(-1); + } + bads[nbads++] = bn; + return(0); + } if (errors[FE_TOTAL] >= MAXBADDESC) { printf("Too many bad sectors\n"); - return; + return(-1); } if (errors[FE_SSE] >= MAXBADDESC) { printf("Too many skip sector errors\n"); - return; + return(-1); } if (errno < EBSE || errno > EHER) - return; + return(0); errno -= EBSE; errors[errno]++; cn = bn / st->nspc; @@ -283,6 +373,7 @@ recorderror(fd, bn, st) /* record the bad sector address and continue */ dkbad.bt_bad[errors[FE_TOTAL]].bt_cyl = cn; dkbad.bt_bad[errors[FE_TOTAL]++].bt_trksec = (tn << 8) + sn; + return(0); } /* @@ -323,8 +414,8 @@ top: printf("\n"); goto top; } - printf("Formatting drive %d on %c%c%d ", - iob[fd - 3].i_unit % 8, cp[0], cp[1], iob[fd - 3].i_unit / 8); + printf("Formatting drive %c%c%d on adaptor %d: ", + cp[0], cp[1], iob[fd - 3].i_unit % 8, iob[fd - 3].i_unit / 8); cp = prompt("verify (yes/no)? "); while (*cp != 'y' && *cp != 'n') cp = prompt("Huh, yes or no? "); @@ -340,6 +431,7 @@ static struct pattern { { 0xf00ff00f, "RH750 worst case" }, { 0xec6dec6d, "media worst case" }, { 0xa5a5a5a5, "alternate 1's and 0's" }, + { 0xFFFFFFFF, "Severe burnin (takes several hours)" }, { 0, 0 }, }; @@ -356,6 +448,9 @@ getpattern() npatterns = p - pat; cp = prompt("Pattern (one of the above, other to restart)? "); pattern = atoi(cp) - 1; + severe = 0; + if (pat[pattern].pa_value == -1) + severe = 1; return (pattern < 0 || pattern >= npatterns); } @@ -375,14 +470,21 @@ bufinit(bp, size) register struct pattern *pptr; register long *pp, *last; register struct xsect *lastbuf; + int patt; size /= sizeof (struct sector); lastbuf = bp + size; - pptr = &pat[pattern]; + if (severe) { + patt = ppat[npat] | ((long)ppat[npat] << 16); + printf("Write pattern 0x%x\n", patt&0xffff); + } else { + pptr = &pat[pattern]; + patt = pptr->pa_value; + } while (bp < lastbuf) { last = &bp->buf[128]; for (pp = bp->buf; pp < last; pp++) - *pp = pptr->pa_value; + *pp = patt; bp++; } } diff --git a/usr/src/sys/vax/stand/hp.c b/usr/src/sys/vax/stand/hp.c index 4330fdad63..09a4c34ae1 100644 --- a/usr/src/sys/vax/stand/hp.c +++ b/usr/src/sys/vax/stand/hp.c @@ -1,4 +1,4 @@ -/* hp.c 6.1 83/07/29 */ +/* hp.c 6.2 83/09/23 */ /* * RP??/RM?? disk driver @@ -173,8 +173,14 @@ restart: /* * Successful data transfer, return. */ - if ((hpaddr->hpds&HPDS_ERR) == 0 && (mba->mba_sr&MBSR_EBITS) == 0) + if ((hpaddr->hpds&HPDS_ERR) == 0 && (mba->mba_sr&MBSR_EBITS) == 0) { + if (io->i_errcnt >= 16) { + hpaddr->hpcs1 = HP_RTC|HP_GO; + while (hpaddr->hpds & HPDS_PIP) + ; + } return (bytecnt); + } /* * Error handling. Calculate location of error. @@ -183,12 +189,14 @@ restart: if (bytesleft) bytesleft |= 0xffff0000; /* sxt */ bn = io->i_bn + (io->i_cc + bytesleft) / sectsiz; + er1 = MASKREG(hpaddr->hper1); + er2 = MASKREG(hpaddr->hper2); + if (er1 & (HPER1_DCK|HPER1_ECH)) + bn--; /* Error is in Prev block */ cn = bn/st->nspc; sn = bn%st->nspc; tn = sn/st->nsect; sn = sn%st->nsect; - er1 = MASKREG(hpaddr->hper1); - er2 = MASKREG(hpaddr->hper2); if (hpdebug[unit] & (HPF_ECCDEBUG|HPF_BSEDEBUG)) { printf("hp error: (cyl,trk,sec)=(%d,%d,%d) ds=%b\n", cn, tn, sn, MASKREG(hpaddr->hpds), HPDS_BITS); @@ -220,8 +228,21 @@ restart: */ if (++io->i_errcnt > 27 || (er1 & HPER1_HARD) || (!ML11 && (er2 & HPER2_HARD))) { - if ((io->i_flgs&F_NBSF) == 0 && hpecc(io, BSE) == 0) - goto success; + /* + * The last ditch effort to bad sector forward + * below will probably fail since mba byte ctr + * (bcr) is different for BSE and ECC errors and + * the wrong block will be revectored to if one + * has 2 contiguous bad blocks and reads the second. + * For now, we can probably just let a header CRC + * error be handled like a BSE since no data will + * have been transferred and the bcr should the same + * as it would with a BSE error. + * --ghg. + */ + if (er1 & HPER1_HCRC) + if ((io->i_flgs&F_NBSF) == 0 && hpecc(io, BSE) == 0) + goto success; hard0: io->i_error = EHER; if (mba->mba_sr & (MBSR_WCKUP|MBSR_WCKLWR)) @@ -280,8 +301,13 @@ skipsect: if (hpecc(io, ECC) == 0) goto success; io->i_error = EECC; + io->i_errblk = bn + ssect[unit]; return (-1); } +#ifdef F_SEVRE + if (io->i_flgs & F_SEVRE) + goto hard; +#endif if (ML11 && (io->i_errcnt >= 16)) goto hard0; /* fall thru to retry */ @@ -293,40 +319,21 @@ skipsect: */ if (((io->i_errcnt & 07) == 4) ) { hpaddr->hpcs1 = HP_RECAL|HP_GO; - hprecal = 1; - goto again; - } - - /* - * Recalibration state machine. - */ - switch (hprecal) { - - case 1: + HPWAIT(hpaddr); hpaddr->hpdc = cn; hpaddr->hpcs1 = HP_SEEK|HP_GO; - hprecal = 2; - goto again; + HPWAIT(hpaddr); + } - case 2: - if (io->i_errcnt < 16 || (io->i_flgs & F_READ) == 0) - goto donerecal; + if (io->i_errcnt >= 16 && (io->i_flgs & F_READ)) { hpaddr->hpof = hp_offset[io->i_errcnt & 017]|HPOF_FMT22; hpaddr->hpcs1 = HP_OFFSET|HP_GO; - hprecal = 3; - goto again; - - case 3: - donerecal: - hprecal = 0; - goto again; - } - if (io->i_errcnt >= 16) { - hpaddr->hpcs1 = HP_RTC|HP_GO; - while (hpaddr->hpds & HPDS_PIP) - ; + HPWAIT(hpaddr); } - goto again; + if (hpdebug[unit] & (HPF_ECCDEBUG|HPF_BSEDEBUG)) + printf("restart: bn=%d, cc=%d, ma=0x%x hprecal=%d\n", + io->i_bn, io->i_cc, io->i_ma, hprecal); + goto restart; /* retry whole transfer --ghg */ success: /* @@ -336,7 +343,6 @@ success: */ bn++; if ((bn-startblock) * sectsiz < bytecnt) { -again: io->i_bn = bn; io->i_ma = membase + (io->i_bn - startblock)*sectsiz; io->i_cc = bytecnt - (io->i_bn - startblock)*sectsiz; @@ -345,6 +351,11 @@ again: io->i_bn, io->i_cc, io->i_ma, hprecal); goto restart; } + if (io->i_errcnt >= 16) { + hpaddr->hpcs1 = HP_RTC|HP_GO; + while (hpaddr->hpds & HPDS_PIP) + ; + } return (bytecnt); } @@ -362,6 +373,8 @@ hpecc(io, flag) if (bcr) bcr |= 0xffff0000; /* sxt */ npf = (bcr + io->i_cc) / sectsiz; /* # sectors read */ + if (flag == ECC) + npf--; /* Error is in prev block --ghg */ bn = io->i_bn + npf + ssect[unit]; /* physical block #*/ if (hpdebug[unit]&HPF_ECCDEBUG) printf("bcr=%d npf=%d ssect=%d sectsiz=%d i_cc=%d\n", @@ -398,6 +411,10 @@ hpecc(io, flag) if ((io->i_flgs & F_ECCLM) && ecccnt++ >= MAXECC) return (1); } +#ifdef F_SEVRE + if (io->i_flgs & F_SEVRE) + return(1); +#endif return (0); } -- 2.20.1