# 2.11BSD#431 - /usr/src/sys/pdpstand/NEW/rabads.c

##### Functions

    blocktest         X
    brchk             X
    deprnt            X
    dipset            X
    dskopen           X
    fembrw            X
    main              X
    prfm              X
    prtdsk            X
    rbempty           X
    rblast            X
    rbmatch           X
    rbnull            X
    rctmcr            X
    rctmcw            X
    rctrev            X
    rp_rcte           X
    yes               X

##### Variables

    allflag           X
    ask               X
    badcnt            X
    bbr_recur         X
    bdwarn            X
    bn                X
    bp_ir             X
    bp_rci            X
    bp_rct1           X
    bp_rct2           X
    bp_tmp            X
    bp_tp             X
    buf               X
    cmd               X
    cn                X
    dip               X
    dkinfo            X
    dn                X
    dt                X
    fd                X
    feb_nc1           X
    feb_nc2           X
    fewarn            X
    first_level       X
    firstblk          X
    fn                X
    force             X
    help              X
    line              X
    nb                X
    nbc               X
    nblk              X
    ndemsg            X
    nondataerr        X
    off_bottom        X
    off_top           X
    pwstr             X
    rb_bad            X
    rb_uecc           X
    rbn               X
    rcnt              X
    rctcopy           X
    repcnt            X
    rp_blk            X
    rp_bps            X
    rp_delta          X
    rp_didit          X
    rp_dirty          X
    rp_hblk           X
    rp_hoff           X
    rp_irs            X
    rp_l              X
    rp_lbn            X
    rp_oblk           X
    rp_off            X
    rp_ooff           X
    rp_orbd           X
    rp_orbn           X
    rp_prev           X
    rp_pri            X
    rp_r              X
    rp_rbn            X
    rp_sec            X
    rp_wcs7           X
    rp_wcs8           X
    rsize             X
    rwfem             X
    sbn               X
    unit              X
    us                X
    ynline            X

##### Macros

    BB_COOP           X
    BB_NONE           X
    BB_RWRT           X
    BR_BBR            X
    BR_CECC           X
    BR_DEB            X
    BR_FEM            X
    BR_NBBR           X
    BR_NDE            X
    BR_UECC           X
    EF_BBR            X
    EF_BBU            X
    ERR               X
    HELP              X
    MD_CMP            X
    MD_ERR            X
    MD_HCE            X
    MD_PRI            X
    MD_SEC            X
    MD_SREC           X
    NO                X
    NOERR             X
    RCI_BR            X
    RCI_FE            X
    RCI_P1            X
    RCI_P2            X
    RCI_VP            X
    RD                X
    RP_AC             X
    RP_RD             X
    RP_REP            X
    RP_WRT            X
    RW                X
    ST_DAT            X
    ST_MSK            X
    ST_SUC            X
    WRT               X
    YES               X

##### struct's

    dkinfo            X
    rct_rci           X

##### unions's

    rctb              X

       1: /*
       2:  * SCCSID: @(#)rabads.c	3.3	12/30/87
       3:  */
       4: /*
       5:  *		LICENSED FROM DIGITAL EQUIPMENT CORPORATION
       6:  *			       COPYRIGHT (c)
       7:  *		       DIGITAL EQUIPMENT CORPORATION
       8:  *			  MAYNARD, MASSACHUSETTS
       9:  *			      1985, 1986, 1987
      10:  *			   ALL RIGHTS RESERVED
      11:  *
      12:  *	THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT
      13:  *	NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL
      14:  *	EQUIPMENT CORPORATION.  DIGITAL MAKES NO REPRESENTATIONS ABOUT
      15:  *	THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  IT IS
      16:  *	SUPPLIED "AS IS" WITHOUT EXPRESSED OR IMPLIED WARRANTY.
      17:  *
      18:  *	IF THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR ITS LICENSEES
      19:  *	MODIFY THE SOFTWARE IN A MANNER CREATING DERIVATIVE COPYRIGHT
      20:  *	RIGHTS, APPROPRIATE COPYRIGHT LEGENDS MAY BE PLACED ON THE
      21:  *	DERIVATIVE WORK IN ADDITION TO THAT SET FORTH ABOVE.
      22:  */
      23:
      24: /*
      25:  * ULTRIX-11 stand-alone MSCP Disk Initialization
      26:  *
      27:  * Fred Canter
      28:  *	For RX33/RX50, reads all blocks and flags any bad ones.
      29:  *	For RD31/RD32/RD51/RD52/RD53/RD54 reads all blocks and rewrites any bad
      30:  *	blocks to force controller initiated replacement.
      31:  *	For RA60/RA80/RA81, reads all blocks and uses host initiated
      32:  *	replacement to revector any bad blocks.
      33:  *
      34:  * SECRET STUFF:
      35:  *
      36:  *	This program has the following undocumented commands/features,
      37:  *	used mainly for debugging:
      38:  *
      39:  * 1.	The "u" command is commented out. This was an unsuccessful
      40:  *	attempt to unreplace a block. I soon discovered that could
      41:  *	not be done.
      42:  *
      43:  * 2.	The "t all" feature of the table command causes all entries
      44:  *	in the RCT to be printed, not just the ones that represent
      45:  *	replaced blocks. Also allows RCT copy # selection.
      46:  *
      47:  * 3.	The "f" command (requires a simple password) causes the
      48:  *	specified block to be written with the "force error"
      49:  *	modifier. This is used for debugging.
      50:  *
      51:  * NOTE:
      52:  *	This program consists, for the most part, of straight-line
      53:  *	unoptimized code! Its only saving grace is that it works, at
      54:  *	least as far as I can tell so far! -- Fred Canter 8/5/84
      55:  *
      56:  */
      57:
      58: #include "sa_defs.h"
      59: #include <sys/param.h>
      60: #include <sys/inode.h>
      61: #include "saio.h"
      62: #include "ra_saio.h"
      63:
      64: /*#define	DEBUG	1	/* Include conditional code for debugging */
      65:
      66: #define RD  0
      67: #define WRT 1
      68: #define RW  2
      69: #define ERR 0
      70: #define NOERR   1
      71: #define YES 1
      72: #define NO  0
      73: #define HELP    2
      74:
      75: /*
      76:  * Bad block replacement strategy flags
      77:  */
      78: #define BB_COOP 0   /* Use MSCP cooperative replacement */
      79: #define BB_RWRT 1   /* (rd51/rd52) - rewriting a block replaces it */
      80: #define BB_NONE 2   /* RX33/RX50 - no bad block replacement */
      81:
      82: struct dkinfo {
      83:     char    *di_type;   /* type name of disk */
      84:     char    *di_name;   /* ULTRIX-11 disk name */
      85:     daddr_t di_size;    /* size of entire volume in blocks */
      86:     int di_chunk;   /* number of sectors per read */
      87:     int di_flag;    /* replacement strategy to use */
      88:                 /* if set, just rewrite block to replace it. */
      89: } dkinfo[] = {
      90:     "ra60", "ra",   400176L,    32, BB_COOP,
      91:     "ra80", "ra",   236964L,    31, BB_COOP,
      92:     "ra81", "ra",   891072L,    32, BB_COOP,
      93:     "rx33", "rx",   2400L,      10, BB_NONE,
      94:     "rx50", "rx",   800L,       10, BB_NONE,
      95:     "rd31", "rd",   41560L,     20, BB_RWRT,
      96:     "rd32", "rd",   83204L,     20, BB_RWRT,
      97:     "rd51", "rd",   21600L,     18, BB_RWRT,
      98:     "rd52", "rd",   60480L,     18, BB_RWRT,
      99:     "rd53", "rd",   138672L,    18, BB_RWRT, /* RQDX3 NOT OPTIMUM */
     100:     "rd54", "rd",   311200L,    20, BB_RWRT, /* RQDX3 NOT OPTIMUM */
     101:     "rc25", "rc",   50902L,     31, BB_COOP,
     102:     0,
     103: };
     104:
     105: char    buf[512*32];    /* disk read and replacement process buffer */
     106:
     107: /*
     108:  * Bad block replacement process definitions.
     109:  */
     110:
     111:                 /* Command Modifiers */
     112: #define MD_CMP  040000      /* Compare */
     113: #define MD_ERR  010000      /* Force Error */
     114: #define MD_SEC  01000       /* Suppress Error Correction */
     115: #define MD_SREC 0400        /* Suppress Error Recovery */
     116: #define MD_PRI  01      /* Primary replacement block */
     117:
     118:                 /* End Message Flags */
     119: #define EF_BBR  0200        /* Bad block Reported */
     120: #define EF_BBU  0100        /* Bad Block Unreported */
     121:
     122:                 /* Status or Event Codes */
     123: #define ST_MSK  037     /* Status/event code mask */
     124: #define ST_SUC  0       /* Success (includes subcode "normal") */
     125: #define ST_DAT  010     /* Data Error */
     126: #define MD_HCE  0110        /* Header Compare Error */
     127:
     128:                 /* Revector Control Info flags */
     129: #define RCI_VP  02      /* Volume write protect flag */
     130: #define RCI_FE  0200        /* Forced error flag */
     131: #define RCI_BR  020000      /* Bad RBN flag */
     132: #define RCI_P2  040000      /* Phase 2 flag */
     133: #define RCI_P1  0100000     /* Phase 1 flag */
     134:
     135:                 /* Block read check return values */
     136: #define BR_NBBR 0       /* no bad block reported */
     137: #define BR_BBR  1       /* bad block reported */
     138: #define BR_CECC 2       /* correctable ECC error */
     139: #define BR_UECC 3       /* uncorrectable ECC error */
     140: #define BR_NDE  4       /* non data error */
     141: #define BR_FEM  5       /* block written with "force error" modifier */
     142: #define BR_DEB  6       /* data error with bad block reported */
     143:
     144: /*
     145:  * Variables used by the replacement process.
     146:  */
     147:
     148: #ifdef  DEBUG
     149: int rp_bps;         /* interrupt replacement process at step ? */
     150: #endif DEBUG
     151:
     152: daddr_t rp_lbn;         /* LBN of logical block being replaced */
     153: daddr_t rp_rbn;         /* RBN (Replacement Block Number) */
     154: int rp_didit;       /* Says block actually replaced */
     155: int rp_hblk;        /* RCT block of primary RBN descriptor */
     156: int rp_hoff;        /* RCT block offset of primary RBN descriptor */
     157: int rp_blk;         /* Current RCT block being searched */
     158: int rp_off;         /* Current RCT block offset */
     159: int rp_oblk;        /* RCT block number of OLD RBN */
     160: int rp_ooff;        /* RCT block offset of OLD RBN */
     161: int rp_delta;       /* RCT block search offset delta (ping-pong) */
     162:
     163: int rp_irs;         /* Initial read of bad LBN successful */
     164: int rp_wcs7;        /* Step 7, write-compare sucessful */
     165: int rp_wcs8;        /* Step 8, write-compare sucessful */
     166: int rp_prev;        /* LBN was previously replaced */
     167: daddr_t rp_orbn;        /* If previously replaced, OLD RBN */
     168: daddr_t rp_orbd;        /* old RBN descriptor, in case replace fsils */
     169: int rp_pri;         /* RBN is primary replacement block */
     170: int rp_sec;         /* RBN is non-primary replacement block */
     171: int rp_l;           /* Number of LBNs per track */
     172: int rp_r;           /* Number of RBNs per track */
     173: int rp_dirty;       /* Phase (P1 | P2) of interrupted replacement */
     174:
     175: /*
     176:  * Replacement process buffer pointers,
     177:  * segment the read/write buffer for use
     178:  * by the replacement process.
     179:  */
     180:
     181: struct rct_rci *bp_rci = &buf[0]; /* RCT blk 0 - replacement cntrl info */
     182: char *bp_ir = &buf[512];      /* RCT blk 1 - image of bad LBN */
     183: union rctb *bp_rct1 = &buf[1024]; /* RCT blk F - first block being searched */
     184: union rctb *bp_rct2 = &buf[1536]; /* RCT blk S - second block (if needed) */
     185: int *bp_tp = &buf[2048];      /* test data pattern ( 0165555 0133333 ) */
     186: char *bp_tmp = &buf[2560];    /* scratch buffer */
     187:
     188: /*
     189:  * Structure of RCT (Revector Control Table) block 0.
     190:  * Used during bad block replacement.
     191:  */
     192:
     193: struct  rct_rci {
     194:     short   rt_vsn[4];  /* volume serial number */
     195:     short   rt_stat;    /* replacement process status word */
     196:     short   rt_rsvd;    /* reserved ??? */
     197:     union {         /* LBN being replaced */
     198:         short   ri_lbnw[2];
     199:         daddr_t ri_lbnl;
     200:     } rt_lbn;
     201:     union {         /* RBN - replacement block number */
     202:         short   ri_rbnw[2];
     203:         daddr_t ri_rbnl;
     204:     } rt_rbn;
     205:     union {         /* bad RBN - RBN being replaced */
     206:         short   ri_brbw[2];
     207:         daddr_t ri_brbl;
     208:     } rt_brb;
     209:     short   rt_pad[244];    /* bad to 512 byte block */
     210: };
     211:
     212: /*
     213:  * Structure used to access an RCT block
     214:  * containing 128 RBN descriptors. The
     215:  * order (swap hi & lo words) must be reversed
     216:  * because of the way the V7 C compiler stores longs.
     217:  */
     218:
     219: union   rctb {
     220:     daddr_t rbnd_l;     /* Access descriptor as a long */
     221:     short   rbnd_w[2];  /* Access descriptor as two shorts */
     222: };
     223:
     224: /*
     225:  * External variables found in the MSCP disk driver (ra.c).
     226:  * Used to modifier driver operation for bad block
     227:  * replacement and get error status info from the driver.
     228:  */
     229:
     230: #define RP_WRT  1
     231: #define RP_RD   2
     232: #define RP_REP  3
     233: #define RP_AC   4
     234:
     235: extern  union {         /* RABADS RBN for ra.c */
     236:     daddr_t ra_rbnl;
     237:     short   ra_rbnw[2];
     238: } ra_rbn;
     239: extern int  ra_badc;    /* RABADS command flag in ra.c */
     240: extern int  ra_badm;    /* RABADS command modifier in ra.c */
     241: extern int  ra_ctid[];  /* MSCP controller type ID */
     242: extern char *ra_dct[];  /* Controller type name string */
     243: extern int  ra_stat[];  /* MSCP status/event code */
     244: extern int  ra_ecode[]; /* MSCP end code */
     245: extern int  ra_eflags[];    /* MSCP end message flags */
     246: extern struct   ra_drv  ra_drv[3][4];   /* Drive type info */
     247:
     248: struct dkinfo *dip;
     249: daddr_t sbn, us, nblk, nbc, rbn, nb;
     250: daddr_t bn;
     251: int repcnt, badcnt, rsize;
     252: int fd, rcnt;
     253: int ask;        /* flag so table doesn't ask for a return */
     254: int allflag;
     255: int rwfem;
     256: int force;
     257: long    atol();
     258: int cn;
     259: int unit;
     260: char    line[50];
     261: char    fn[30];     /* file spec i.e., hp(0,0) */
     262: char    cmd[20];    /* command name */
     263: char    dt[20];     /* disk type rm03, etc */
     264: char    dn[2];      /* drive number */
     265: int firstblk;   /* flag for linear rct searching */
     266: int off_bottom; /* descriptor in RCT greater that 127 */
     267: int off_top;    /* descriptor in RCT less than zero */
     268: int first_level;    /* have completed first level search of the RCT block */
     269: int nondataerr; /* got a non-data error reading the block in step 7 */
     270: int bbr_recur;  /* BBR recursion counter */
     271:
     272: char    *help[] =
     273: {
     274:     "",
     275:     "To correct typing mistakes, press <DELETE> to erase one character",
     276:     "or <CTRL/U> to erase the entire line.",
     277:     "",
     278:     "To execute a command, type the first letter of the command then",
     279:     "press <RETURN>. The program may prompt for additional information.",
     280:     "",
     281:     "The valid RABADS commands are:",
     282:     "",
     283:     "help    - Print this help message.",
     284:     "",
     285:     "exit    - Exit from the RABADS program.",
     286:     "",
     287:     "drives  - List the disks that can be initialized with RABADS.",
     288:     "",
     289:     "status  - Print the status and geometry of the specified disk.",
     290:     "",
     291:     "table   - Print the RCT (Revector Control Table) for a disk.",
     292:     "",
     293:     "init    - Do a read scan of the disk and replace any bad blocks.",
     294:     "",
     295:     "replace - Force replacement of a disk block.",
     296:     "",
     297:     0
     298: };
     299:
     300: char    *fewarn[] =
     301: {
     302:     "",
     303:     "The block was written with the \"force error\" modifier, that is,",
     304:     "when the block is read report an error even if the read succeeds.",
     305:     "This indicates that the block has already been replaced but that",
     306:     "valid data could not be recovered from the bad block before it",
     307:     "was replaced. This may also indicate that a previous attempt to",
     308:     "replace the block failed for some reason. In either case, the",
     309:     "recommended procedure is to rewrite the block then reread it and",
     310:     "only replace the block if the reread fails.",
     311:     "",
     312:     "		    ****** CAUTION ******",
     313:     "",
     314:     "Rewriting the block will clear the \"forced error\", however, the",
     315:     "data in the block must be considered to have been corrupted. This",
     316:     "is because valid data could not be read from the block before it",
     317:     "was replaced.",
     318:     "",
     319:     0
     320: };
     321:
     322: char    *bdwarn =
     323:   "\n\n\7\7\7DISK SHOULD NOT BE USED: \
     324:   \n    (has unreplaced bad blocks or uncleared \"forced error\" blocks!)\n";
     325: char    *pwstr = "qwerty";
     326: char    *feb_nc1 =
     327:   "was written with \"forced error\" - NOT CLEARED!\n";
     328: char    *feb_nc2 =
     329:   "(Data in this block must considered invalid!)\n";
     330: char    *ndemsg =
     331:   "(NON DATA ERROR: suspect faulty disk hardware or bad media!)\n";
     332: char    *rb_uecc =
     333:   "(Uncorrectable ECC error in replacement block!)\n";
     334: char    *rb_bad =
     335:   "(Hardware says replacement block bad, retry disk initialization!)\n";
     336:
     337: extern int argflag; /* 0=interactive, 1=called by sdload */
     338: int rctcopy;
     339:
     340: main()
     341: {
     342:     struct rct_rci *rtp;
     343:     register int i, j;
     344:     register char *p;
     345:     int s, cnt, k;
     346:     int found, rctend, rctrw;
     347:     long    *lp;
     348:
     349:     printf("\n\nULTRIX-11 MSCP Disk Initialization Program\n");
     350:     if(argflag) {   /* called by SDLOAD, can only do init command */
     351:         cmd[0] = 'i';
     352:         cmd[1] = '\0';
     353:         goto do_i;
     354:     }
     355: retry:
     356:     ask = 1;
     357:     force = 0;
     358:     allflag = 0;
     359:     rctcopy = 0;
     360:     printf("\nrabads <help exit drives status table init replace>: ");
     361:     gets(cmd);
     362:     switch(cmd[0]) {
     363:     case 'f':
     364:         goto do_f;
     365:     case 'h':
     366:         for(i=0; help[i]; i++)
     367:             printf("\n%s", help[i]);
     368:         goto retry;
     369:     case 'e':
     370:         exit(NORMAL);
     371:     case 'd':
     372:         prtdsk();
     373:         goto retry;
     374:     case 's':
     375:         goto do_s;
     376:     case 't':
     377:         if(strcmp("t all", cmd) == 0)
     378:             allflag++;  /* print entire RCT */
     379:         if(strcmp("t go", cmd) == 0){
     380:             ask = 0;    /* don't stop to ask */
     381:             allflag++;  /* print entire RCT */
     382:         }
     383:         goto do_t;
     384:     case 'r':
     385:         goto do_r;
     386:     case 'i':
     387:         goto do_i;
     388:     case 0:
     389:         goto retry;
     390:     default:
     391:         printf("\n(%s) - not a valid command!\n", cmd);
     392:         goto retry;
     393:     }
     394: do_s:
     395:     if(dipset() < 0)
     396:         goto retry;
     397:     dskopen(NOERR, RD);
     398:     if(fd >= 0)
     399:         close(fd);
     400:     printf("\nMSCP controller: %s at micro-code revision %d",
     401:         ra_dct[cn], ra_ctid[cn] & 017);
     402:     printf("\nUnit %d: ", unit);
     403:     switch(ra_drv[cn][unit].ra_dt) {
     404:     case RC25:
     405:         printf("RC25");
     406:         break;
     407:     case RX33:
     408:         printf("RX33");
     409:         break;
     410:     case RX50:
     411:         printf("RX50");
     412:         break;
     413:     case RD31:
     414:         printf("RD31");
     415:         break;
     416:     case RD32:
     417:         printf("RD32");
     418:         break;
     419:     case RD51:
     420:         printf("RD51");
     421:         break;
     422:     case RD52:
     423:         printf("RD52");
     424:         break;
     425:     case RD53:
     426:         printf("RD53");
     427:         break;
     428:     case RD54:
     429:         printf("RD54");
     430:         break;
     431:     case RA60:
     432:         printf("RA60");
     433:         break;
     434:     case RA80:
     435:         printf("RA80");
     436:         break;
     437:     case RA81:
     438:         printf("RA81");
     439:         break;
     440:     default:
     441:         printf("UKNOWN or NONEXISTENT");
     442:         break;
     443:     }
     444:     printf(" status =");
     445:     if(ra_drv[cn][unit].ra_online)
     446:         printf(" ONLINE");
     447:     else
     448:         printf(" OFFLINE");
     449:     printf("\nLogical blocks per track\t= %d",
     450:         ra_drv[cn][unit].ra_trksz);
     451:     printf("\nReplacement blocks per track\t= %d",
     452:         ra_drv[cn][unit].ra_rbns);
     453:     printf("\nNumber of RCT copies\t\t= %d", ra_drv[cn][unit].ra_ncopy);
     454:     printf("\nSize of each RCT copy in blocks\t= %d",
     455:         ra_drv[cn][unit].ra_rctsz);
     456:     printf("\nHost area size in blocks\t= %D\n",
     457:         ra_drv[cn][unit].d_un.ra_dsize);
     458:     goto retry;
     459: do_u:       /* semi-secret stuff (unreplace block(s)) */
     460: /*
     461:  *******************************************************************************
     462: 	printf("\nPassword: ");
     463: 	gets(line);
     464: 	if(strcmp("farkle", line) != 0) {
     465: 		printf("\nReserved for Digital!\n");
     466: 		goto retry;
     467: 	}
     468: 	if(dipset() < 0)
     469: 		goto retry;
     470: 	dskopen(NOERR, RW);
     471: 	if(fd < 0) {
     472: 		printf("\nCan't open %s!\n", fn);
     473: 		goto retry;
     474: 	}
     475: 	if(rp_dirty) {
     476: 		printf("\nUnreplace aborted!\n");
     477: 		goto do_u_x;
     478: 	}
     479: 	s = ra_drv[cn][unit].ra_rctsz;
     480: 	if(s == 0) {
     481: 		printf("\nDisk does not have a Revector Control Table!");
     482: 		goto do_u_x;
     483: 	}
     484: do_u_bn:
     485: 	if(allflag == 0) {
     486: 		printf("\nBlock number: ");
     487: 		gets(line);
     488: 		if(line[0] == '\0')
     489: 			goto do_u_bn;
     490: 		bn = atol(line);
     491: 		if((bn < 0) || (bn >= ra_drv[cn][unit].d_un.ra_dsize))
     492: 			goto do_u_bn;
     493: 	}
     494: 	rctend = 0;
     495: 	rctrw = 0;
     496: 	for(i=2; i<s; i++) {
     497: 		if(rctmcr(i, bp_rct1) < 0) {
     498: 			printf("\nRCT multicopy read failed!\n");
     499: 			goto do_u_x;
     500: 		}
     501: 		found = 0;
     502: 		for(j=0; j<128; j++) {
     503: 			k = (bp_rct1[j].rbnd_w[0] >> 12) & 017;
     504: 			switch(k) {
     505: 			case 02:
     506: 			case 03:
     507: 				if(allflag) {
     508: 					found++;
     509: 					bp_rct1[j].rbnd_l = 0L;
     510: 					break;
     511: 				}
     512: 				if(bn == (bp_rct1[j].rbnd_l & ~036000000000)) {
     513: 					found++;
     514: 					bp_rct1[j].rbnd_l = 0L;
     515: 				}
     516: 				break;
     517: 			case 07:
     518: 				if(((ra_ctid[cn] >> 4) & 017) == RQDX1) {
     519: 					rctend++;
     520: 					break;
     521: 				} else
     522: 					continue;
     523: 			case 010:
     524: 				rctend++;
     525: 				break;
     526: 			default:
     527: 				continue;
     528: 			}
     529: 		}
     530: 		if(found) {
     531: 			if(rctmcw(i, bp_rct1) < 0) {
     532: 				printf("\nPANIC: RCT multicopy write failed!\n");
     533: 				exit(FATAL);
     534: 			}
     535: 			rctrw++;
     536: 		}
     537: 		if(rctend) {
     538: 			if(rctrw == 0)
     539: 				printf("\nBlock %D was not revectored!\n", bn);
     540: 			break;
     541: 		}
     542: 	}
     543:  *******************************************************************************
     544:  */
     545: do_u_x:
     546:     close(fd);
     547:     printf("\n");
     548:     goto retry;
     549: do_r:
     550:     if(dipset() < 0)
     551:         goto retry;
     552:     if(dip->di_flag == BB_NONE) {
     553:         printf("\nCannot replace blocks on an %s disk!\n",
     554:             dip->di_type);
     555:         goto retry;
     556:     }
     557:     dskopen(NOERR, RW);
     558:     if(fd < 0) {
     559:         printf("\nCan't open %s!\n", fn);
     560:         goto retry;
     561:     }
     562:     if(rp_dirty)
     563:         goto rp_s1; /* finish up interrupted replacement */
     564:     if(ra_drv[cn][unit].ra_rctsz == 0) {
     565:         printf("\nDisk does not have a Revector Control Table!");
     566:         goto do_u_x;
     567:     }
     568: do_r_bn:
     569:     printf("\nBlock number: ");
     570:     gets(line);
     571:     if(line[0] == '\0')
     572:         goto do_r_bn;
     573:     bn = atol(line);
     574:     if((bn < 0) || (bn >= ra_drv[cn][unit].d_un.ra_dsize))
     575:         goto do_r_bn;
     576:     if(dip->di_flag == BB_RWRT) {   /* cntlr will replace block if bad */
     577:         lseek(fd, (long)(bn*512), 0);
     578:         ra_badc = RP_RD;
     579:         read(fd, (char *)&buf, 512);
     580:     }
     581:     printf("\nBlock %D read check: ", bn);
     582:     s = brchk(bn);  /* read check block - see if really bad */
     583:     if((s == BR_BBR) || (s == BR_NBBR))
     584:         printf("SUCCEEDED - ");
     585:     else
     586:         printf("FAILED - ");
     587:     switch(s) {
     588:     case BR_BBR:
     589:     case BR_DEB:
     590:         printf("bad block reported\n");
     591:         break;
     592:     case BR_NBBR:
     593:         printf("no bad block reported\n");
     594:         if(dip->di_flag == BB_RWRT) {
     595:             printf("\n\7\7\7Disk controller replaces bad blocks,");
     596:             printf(" no way to force replacement!\n");
     597:             goto do_u_x;
     598:         }
     599:         printf("\nReally replace this block <y or n> ? ");
     600:         if(yes(0) == YES)
     601:             break;
     602:         else
     603:             goto do_u_x;
     604:     case BR_CECC:
     605:     case BR_UECC:
     606:         printf("data error\n");
     607:         break;
     608:     case BR_NDE:
     609:         printf("non data error\n");
     610:         printf("\n** - block connot be replaced!\n");
     611:         goto do_u_x;
     612:     case BR_FEM:
     613:         printf("block written with \"force error\" modifier\n");
     614:         for(i=0; fewarn[i]; i++)
     615:             printf("\n%s", fewarn[i]);
     616:         printf("\nRewrite the block <y or n> ? ");
     617:         if(yes(0) == NO)
     618:             goto do_u_x;
     619:         lseek(fd, (long)(bn*512), 0);
     620:         ra_badc = RP_WRT;
     621:         if(write(fd, (char *)bp_tmp, 512) != 512) {
     622:             printf("\n\7\7\7BLOCK REWRITE FAILED!\n");
     623:             goto do_u_x;
     624:         }
     625:         lseek(fd, (long)(bn*512), 0);
     626:         ra_badc = RP_RD;
     627:         if(dip->di_flag == BB_RWRT)
     628:             goto do_r_rq;
     629:         if(read(fd, (char *)bp_tmp, 512) == 512)
     630:             printf("\nREREAD SUCCEEDED: block not replaced!\n");
     631:         else
     632:             printf("\nREREAD FAILED: retry the replace command!\n");
     633:         goto do_u_x;
     634: do_r_rq:
     635:         if(read(fd, (char *)bp_tmp, 512) != 512) {
     636:             printf("\n\7\7\7Disk controller failed ");
     637:             printf("to replace bad block!\n");
     638:         } else
     639:             printf("\nDisk controller replaced block!\n");
     640:         goto do_u_x;
     641:     }
     642:     if(dip->di_flag == BB_COOP) {
     643:         printf("\nBLOCK: %D - replacement ", bn);
     644:         force++;    /* force replacement (see rp_s8:) */
     645:         rp_lbn = bn;
     646:         goto rp_s1;
     647:     }
     648:     goto do_u_x;
     649: do_f:
     650:     printf("\nPassword: ");
     651:     gets(line);
     652:     if(strcmp(line, pwstr) != 0) {
     653:         printf("\nSorry - reserved for Digital!\n");
     654:         goto retry;
     655:     }
     656:     if(dipset() < 0)
     657:         goto retry;
     658:     if(dip->di_flag == BB_NONE) {
     659:         printf("\nCannot replace blocks on an %s disk!\n",
     660:             dip->di_type);
     661:         goto retry;
     662:     }
     663:     dskopen(NOERR, RW);
     664:     if(fd < 0) {
     665:         printf("\nCan't open %s!\n", fn);
     666:         goto retry;
     667:     }
     668:     if(rp_dirty) {
     669:         printf("\nForce aborted!\n");
     670:         goto do_u_x;
     671:     }
     672:     if(ra_drv[cn][unit].ra_rctsz == 0) {
     673:         printf("\nDisk does not have a Revector Control Table!");
     674:         goto do_u_x;
     675:     }
     676: do_f_bn:
     677:     printf("\nBlock number: ");
     678:     gets(line);
     679:     if(line[0] == '\0')
     680:         goto do_f_bn;
     681:     bn = atol(line);
     682:     if((bn < 0) || (bn >= ra_drv[cn][unit].d_un.ra_dsize))
     683:         goto do_f_bn;
     684:     lseek(fd, (long)(bn*512), 0);
     685:     read(fd, buf, 512);
     686:     lseek(fd, (long)(bn*512), 0);
     687:     ra_badc = RP_WRT;
     688:     ra_badm = 010000;   /* MD_ERR (force error) */
     689:     write(fd, buf, 512);
     690:     goto do_u_x;
     691: do_t:
     692:     if(dipset() < 0)
     693:         goto retry;
     694:     dskopen(NOERR, RD);
     695:     if(fd < 0) {
     696:         printf("\nCan't open %s!\n", fn);
     697:         goto retry;
     698:     }
     699:     s = ra_drv[cn][unit].ra_rctsz;
     700:     if(s == 0) {
     701:         printf("\nDisk does not have a Revector Control Table!");
     702:         goto do_t_x;
     703:     }
     704:     if(allflag == 0)    /* if "t all" ask which copy */
     705:         goto do_t_n;
     706:     printf("\nRCT copy < ");
     707:     k = ra_drv[cn][unit].ra_ncopy;
     708:     for(i=0; i<k; i++)
     709:         printf("%d ", i+1);
     710:     printf(">: ");
     711:     gets(line);
     712:     rctcopy = atoi(line);
     713:     if((rctcopy < 0) || (rctcopy > k))
     714:         rctcopy = 0;
     715:     if(rctmcr(0, bp_rci) < 0)
     716:         goto do_t_err;
     717:     rtp = bp_rci;
     718:     i = rtp->rt_lbn.ri_lbnw[0]; /* reverse order */
     719:     rtp->rt_lbn.ri_lbnw[0] = rtp->rt_lbn.ri_lbnw[1];
     720:     rtp->rt_lbn.ri_lbnw[1] = i;
     721:     i = rtp->rt_rbn.ri_rbnw[0]; /* reverse order */
     722:     rtp->rt_rbn.ri_rbnw[0] = rtp->rt_rbn.ri_rbnw[1];
     723:     rtp->rt_rbn.ri_rbnw[1] = i;
     724:     i = rtp->rt_brb.ri_brbw[0]; /* reverse order */
     725:     rtp->rt_brb.ri_brbw[0] = rtp->rt_brb.ri_brbw[1];
     726:     rtp->rt_brb.ri_brbw[1] = i;
     727:     printf("\nRCT block 0: revector control information.\n");
     728:     printf("\nStatus bits: P1=%d ", rtp->rt_stat&RCI_P1 ? 1 : 0);
     729:     printf("P2=%d ", rtp->rt_stat&RCI_P2 ? 1 : 0);
     730:     printf("BR=%d ", rtp->rt_stat&RCI_BR ? 1 : 0);
     731:     printf("FE=%d ", rtp->rt_stat&RCI_FE ? 1 : 0);
     732:     printf("VP=%d ", rtp->rt_stat&RCI_VP ? 1 : 0);
     733:     printf("\nBad LBN\t= %D", rtp->rt_lbn.ri_lbnl);
     734:     printf("\nRBN\t= %D", rtp->rt_rbn.ri_rbnl);
     735:     printf("\nOld RBN\t= %D\n", rtp->rt_brb.ri_brbl);
     736:     printf("\nOctal dump RCT block 1 <y or n> ? ");
     737:     gets(line);
     738:     if(line[0] != 'y')
     739:         goto do_t_n;
     740:     if(rctmcr(1, bp_ir) < 0)
     741:         goto do_t_err;
     742:     printf("\nRCT block 1 contents:\n");
     743:     for(i=0; i<256; i++) {
     744:         if((i%8) == 0)
     745:             printf("\n    ");
     746:         printf("%o\t", bp_ir[i]);
     747:         if(i == 127)
     748:             if (ask)
     749:                 if(prfm())
     750:                     goto do_t_x;
     751:     }
     752:     if (ask)
     753:         if(prfm())
     754:             goto do_t_x;
     755: do_t_n:
     756:     cnt = -1;
     757:     for(i=2; i<s; i++) {
     758:         if(rctmcr(i, bp_rct1) < 0) {
     759: do_t_err:
     760:             printf("\nCANNOT READ REVECTOR CONTROL TABLE: ");
     761:             printf("RCT multicopy read failed!\n");
     762:             goto do_t_x;
     763:         }
     764:         for(j=0; j<128; j++) {
     765:             if((cnt == 16) || (cnt == -1)) {
     766:                 if(cnt == 16)
     767:                     if (ask)
     768:                         if(prfm())
     769:                             goto do_t_x;
     770:                 cnt = 0;
     771:                 printf("\nBlock\tOffset\tLBN\tCODE");
     772:                 printf("\n-----\t------\t---\t----");
     773:             }
     774:             k = (bp_rct1[j].rbnd_w[0] >> 12) & 017;
     775:             switch(k) {
     776:             case 02:
     777:             case 03:
     778:             case 04:
     779:             case 05:
     780:                 break;
     781:             case 07:
     782:                 if(((ra_ctid[cn] >> 4) & 017) == RQDX1) {
     783:                     if(allflag)
     784:                         break;
     785:                     else
     786:                         goto do_t_x;
     787:                 } else
     788:                     continue;
     789:             case 010:
     790:                 goto do_t_x;
     791:             default:
     792:                 if(allflag)
     793:                     break;
     794:                 else
     795:                     continue;
     796:             }
     797:             cnt++;
     798:             printf("\n%d\t%d\t%D\t", i, j,
     799:                 bp_rct1[j].rbnd_l & ~036000000000);
     800:             switch(k) {
     801:             case 00:
     802:                 printf("Unallocated replacement block");
     803:                 break;
     804:             case 02:
     805:                 printf("Allocated - primary RBN");
     806:                 break;
     807:             case 03:
     808:                 printf("Allocated - non-primary RBN");
     809:                 break;
     810:             case 04:
     811:             case 05:
     812:                 printf("Unusable replacement block");
     813:                 break;
     814:             default:
     815:                 printf("Unknown code (%o)", k);
     816:                 break;
     817:             }
     818:         }
     819:     }
     820: do_t_x:
     821:     close(fd);
     822:     printf("\n");
     823:     goto retry;
     824: do_i:
     825:     if(dipset() < 0)
     826:         goto retry;
     827:     dskopen(ERR, RW);
     828:     if(rp_dirty) {
     829:         printf("\nInitialization aborted!\n");
     830:         goto do_u_x;
     831:     }
     832:     us = ra_drv[cn][unit].d_un.ra_dsize;
     833:     printf("\nStarting block number < 0 >: ");
     834:     gets(line);
     835:     if(line[0] == '\0')
     836:         sbn = 0L;
     837:     else {
     838:         sbn = atol(line);
     839:         if((sbn < 0) || (sbn >= us)) {
     840:             printf("\nBad starting block!\n");
     841:     do_i_ex:
     842:             if(argflag)
     843:                 exit(FATAL);
     844:             else
     845:                 goto retry;
     846:         }
     847:     }
     848:     printf("\nNumber of blocks to check < %D >: ", us - sbn);
     849:     gets(line);
     850:     if(line[0] == '\0')
     851:         nblk = us - sbn;
     852:     else
     853:         nblk = atol(line);
     854:     if(nblk <= 0) {
     855:         printf("\nBad # of blocks!\n");
     856:         goto do_i_ex;
     857:     }
     858:     if(nblk > (us - sbn)) {
     859:         nblk = (us - sbn);
     860:         printf("\nToo many blocks, truncating to %D blocks!\n", nblk);
     861:     }
     862: do_i_rw:
     863:     if(dip->di_flag != BB_NONE) {
     864:         if(argflag == 0) {
     865:         printf("\nRewrite blocks written with \"forced error\" ");
     866:         printf("(? for help) <y or n> ? ");
     867:         rwfem = yes(HELP);
     868:         if(rwfem == HELP) {
     869:             for(i=0; fewarn[i]; i++)
     870:                 printf("\n%s", fewarn[i]);
     871:             goto do_i_rw;
     872:         }
     873:         } else
     874:         rwfem = YES;
     875:     }
     876:     printf("\nREADING...\n");
     877:     badcnt = 0;
     878:     repcnt = 0;
     879:     bn = sbn;
     880:     nbc = 0;
     881: do_i_lp:
     882:     nb = dip->di_chunk;
     883:     if((bn + nb) > us)
     884:         nb = (us - bn);
     885:     if((nb + nbc) > nblk)
     886:         nb = nblk - nbc;
     887:     rsize = nb * 512;
     888:     lseek(fd, (long)(bn*512), 0);
     889:     ra_badc = RP_AC;
     890:     rcnt = read(fd, (char *)&buf, rsize);
     891:     if(rcnt == rsize) {
     892: do_i_lp1:
     893:         bn += nb;
     894:         nbc += nb;
     895:         if(nbc >= nblk) {
     896: bg_loop:
     897:             close(fd);
     898:             printf("\n\n%D blocks checked", nbc);
     899:             printf("\n%d bad blocks found", badcnt);
     900:             printf("\n%d bad blocks replaced\n", repcnt);
     901:             if(argflag == 0) {
     902:                 if(repcnt != badcnt)
     903:                     printf("%s", bdwarn);
     904:                 else
     905:                     printf("\n");
     906:                 goto retry;
     907:             }
     908:             if(repcnt != badcnt)
     909:                 exit(HASBADS);
     910:             while(getchar() != '\n') ;  /* wait for <RETURN> */
     911:             exit(NORMAL);
     912:         }
     913:         goto do_i_lp;
     914:     }
     915:     for(rbn=bn; rbn<(bn+nb); rbn++) {
     916:         lseek(fd, (long)(rbn*512), 0);
     917:         ra_badc = RP_RD;
     918:         rcnt = read(fd, (char *)&buf, 512);
     919:         if(rcnt == 512)
     920:             continue;
     921:         badcnt++;
     922:         printf("\nBLOCK: %D - ", rbn);
     923:         switch(dip->di_flag) {  /* replacement strategy to use */
     924:         case BB_COOP:
     925:             if(ra_eflags[cn] & EF_BBR) {
     926:                 printf("replacement ");
     927:                 rp_lbn = rbn;
     928:                 goto rp_s1; /* go replace block */
     929:             } else if(ra_stat[cn] == ST_DAT) {  /* FEM */
     930:                 /* data error with force error modifier */
     931: do_i_rs:
     932:                 if(!rwfem) { /* NOT REWRITING FORCED ERRORS */
     933:                     printf("%s", feb_nc1); /* warn bad data */
     934:                     printf("%s", feb_nc2);
     935:                 } else {
     936:                     if(fembrw(0, rbn) == YES)
     937:                         badcnt--;
     938:                 }
     939:                 break;
     940:             } else {
     941:                 printf("(no bad block reported flag) ");
     942:                 printf("cannot be replaced!\n");
     943:                 deprnt();
     944:                 break;
     945:             }
     946: do_i_rg:            /* return here if replacement succeeded */
     947:             repcnt++;
     948:             printf("SUCCEEDED!\n");
     949:             s = brchk(rbn); /* read check replacement block */
     950:             if(s == BR_NBBR)
     951:                 break;  /* every thing is cool! */
     952:             if(s == BR_FEM) { /* replacement block - forced error */
     953:                 if(!rwfem) {
     954:                     printf("BLOCK: %D - ", rbn);
     955:                     printf("%s", feb_nc1);
     956:                     printf("%s", feb_nc2);
     957:                     repcnt--;
     958:                     break;
     959:                 }
     960:                 if(fembrw(1, rbn) == NO)
     961:                     repcnt--;
     962:                 break;
     963:             }
     964:             repcnt--;
     965:             printf("BLOCK: %D - ", rbn);
     966:             printf("replacement block read check FAILED!\n");
     967:             switch(s) {
     968:             case BR_UECC:
     969:                 printf("%s", rb_uecc);
     970:                 deprnt();
     971:                 break;
     972:             case BR_BBR:
     973:                 printf("%s", rb_bad);
     974:                 /* BAD REPLACEMENT BLOCK ?????? */
     975:                 /* should go back and rescan */
     976:                 break;
     977:             case BR_NDE:
     978:             default:
     979:                 printf("%s", ndemsg);
     980:                 deprnt();
     981:                 break;
     982:             }
     983:             break;
     984: do_i_rb:            /* return here if replacement failed */
     985:             printf("\nBLOCK: %D - replacement FAILED!\n", rbn);
     986:             break;
     987: do_i_ra:            /* return here if replacement aborted */
     988:                 /* i.e., block was not really bad */
     989:             printf("ABORTED (block not really bad)!\n");
     990:             lseek(fd, (long)(rbn*512), 0);
     991:             ra_badc = RP_RD;
     992:             read(fd, (char *)&buf, 512);
     993:             if(ra_stat[cn] != ST_DAT) {
     994:                 badcnt--;
     995:                 break;  /* NOT FORCED ERROR */
     996:             }
     997:             if(!rwfem) {
     998:                 printf("BLOCK: %D - ", rbn);
     999:                 printf("%s", feb_nc1);
    1000:                 printf("%s", feb_nc2);
    1001:                 break;
    1002:             }
    1003:             if(fembrw(1, rbn) == YES)
    1004:                 badcnt--;
    1005:             break;
    1006:         case BB_NONE:
    1007:             printf("%s: bad blocks cannot be replaced!\n",
    1008:                 dip->di_type);
    1009:             deprnt();
    1010:             break;
    1011:         case BB_RWRT:
    1012:             if(ra_eflags[cn] & EF_BBR) {
    1013:                 printf("replacement ");
    1014:                 switch(brchk(rbn)) {    /* read check */
    1015:                 case BR_NBBR:
    1016:                     repcnt++;
    1017:                     printf("SUCCEEDED!\n");
    1018:                     break;
    1019:                 case BR_FEM:
    1020:                     printf("SUCCEEDED!\n");
    1021:                     repcnt++;
    1022:                     if(!rwfem) {
    1023:                         printf("BLOCK: %D - ", rbn);
    1024:                         printf("%s", feb_nc1);
    1025:                         printf("%s", feb_nc2);
    1026:                         repcnt--;
    1027:                         break;
    1028:                     }
    1029:                     if(fembrw(1, rbn) == NO)
    1030:                         repcnt--;
    1031:                     break;
    1032:                 case BR_UECC:
    1033:                     printf("FAILED!\n");
    1034:                     printf("%s", rb_uecc);
    1035:                     deprnt();
    1036:                     break;
    1037:                 case BR_BBR:
    1038:                     printf("FAILED!\n");
    1039:                     printf("%s", rb_bad);
    1040:                     /* BAD REPLACEMENT BLOCK ?????? */
    1041:                     /* should go back and rescan */
    1042:                     break;
    1043:                 case BR_NDE:
    1044:                 default:
    1045:                     printf("FAILED!\n");
    1046:                     printf("%s", ndemsg);
    1047:                     deprnt();
    1048:                     break;
    1049:                 }
    1050:             } else if(ra_stat[cn] == ST_DAT) { /* FEM */
    1051:                 if(!rwfem) { /* NOT REWRITING FORCED ERRORS */
    1052:                     printf("%s", feb_nc1); /* warn bad data */
    1053:                     printf("%s", feb_nc2);
    1054:                 } else {
    1055:                     if(fembrw(0, rbn) == YES)
    1056:                         badcnt--;
    1057:                 }
    1058:             } else {
    1059:                 printf("cannot be replaced!\n");
    1060:                 printf("%s", ndemsg);
    1061:                 deprnt();
    1062:             }
    1063:             break;
    1064:         }
    1065:     }
    1066:     goto do_i_lp1;
    1067:
    1068: /*
    1069:  * MSCP: host initiated bad block replacement algorithm
    1070:  *
    1071:  * I allow myself one editorial comment before proceeding:
    1072:  *
    1073:  *	Fred Canter "Good GOD Gertrude, you must be kidding!"
    1074:  *
    1075:  * Each step of the bad block replacement procedure is labeled
    1076:  * so as to correspond to the steps in section 7.5 of the "DSA
    1077:  * DISK FORMAT SPECIFICATION" Version 1.4.0.
    1078:  */
    1079:
    1080: rp_s1:
    1081: #ifdef  DEBUG
    1082:     if(rp_bps == 1)
    1083:         goto do_u_x;
    1084: #endif	DEBUG
    1085: /*
    1086:  * Step 1 is performed elsewhere in the program. Either the replacement
    1087:  * process is initilated by an error with the BAD BLOCK REPORTED flag set,
    1088:  * or the process is restarted because it was interrupted by a failure of
    1089:  * some type. The latter case is detected when the unit is prought online.
    1090:  */
    1091:     rp_didit = 0;   /* clear block actually replaced indicator */
    1092:             /* in case of interrupted replacement */
    1093:     rp_prev = rp_pri = rp_sec = 0;
    1094:
    1095: rp_s2:
    1096: #ifdef  DEBUG
    1097:     if(rp_bps == 2)
    1098:         goto do_u_x;
    1099: #endif	DEBUG
    1100: /*
    1101:  * The DSA spec calls for a soft lock of the unit, but because replacement
    1102:  * is only done by this stand-alone program a lock is not necessary.
    1103:  */
    1104:
    1105: bbr_recur = 0;      /* initialize the BBR recursion counter to 0 */
    1106:
    1107: rp_s3:
    1108: #ifdef  DEBUG
    1109:     if(rp_bps == 3)
    1110:         goto do_u_x;
    1111: #endif	DEBUG
    1112: /*
    1113:  * The first two steps were easy, but I don't expect this trend to continue.
    1114:  */
    1115:
    1116:     if(rp_dirty == 0)
    1117:         goto rp_s4; /* NOT an interrupted replacement! */
    1118: /*
    1119:  * Interrupted replacement,
    1120:  * Re-establish software context for Phase 1
    1121:  * and Phase 2, if necessary.
    1122:  * Yes, I know that RCT block 0 was read in
    1123:  * during the dskopen()!
    1124:  */
    1125:     printf("\n\7\7\7COMPLETING INTERRUPTED BAD BLOCK REPLACEMENT");
    1126:     printf(" (Phase %d)...\n", rp_dirty);
    1127:     if(rctmcr(0, bp_rci) < 0) { /* revector control info */
    1128:         rp_rcte(3, RD, 0);
    1129:         goto rp_s18;
    1130:     }
    1131:     if(rctmcr(1, bp_ir) < 0) {  /* bad LBN image */
    1132:         rp_rcte(3, RD, 1);
    1133:         goto rp_s18;
    1134:     }
    1135:     rtp = (struct rct_rci *)bp_rci;
    1136:     if(rtp->rt_stat & RCI_FE)   /* initial read sucessful or not */
    1137:         rp_irs = NO;
    1138:     else
    1139:         rp_irs = YES;
    1140: /*
    1141:  * The DSA spec says that the LBN is only valid
    1142:  * if the P1 bit is set, but I don't buy it!
    1143:  * I never clear the LBN until after phase 2 is
    1144:  * complete or a fatal error.
    1145:  */
    1146:     i = rtp->rt_lbn.ri_lbnw[0]; /* reverse order */
    1147:     rtp->rt_lbn.ri_lbnw[0] = rtp->rt_lbn.ri_lbnw[1];
    1148:     rtp->rt_lbn.ri_lbnw[1] = i;
    1149:     rp_lbn = rtp->rt_lbn.ri_lbnl;   /* bad block's LBN */
    1150:     printf("\nBLOCK: %D - replacement ", rp_lbn);
    1151:     if(rp_dirty == 1)
    1152:         goto rp_s7; /* Interrupted during phase one */
    1153:     i = rtp->rt_rbn.ri_rbnw[0]; /* new RBN - reverse order */
    1154:     rtp->rt_rbn.ri_rbnw[0] = rtp->rt_rbn.ri_rbnw[1];
    1155:     rtp->rt_rbn.ri_rbnw[1] = i;
    1156:     rp_rbn = rtp->rt_rbn.ri_rbnl;
    1157:     i = rtp->rt_brb.ri_brbw[0]; /* old RBN - reverse order */
    1158:     rtp->rt_brb.ri_brbw[0] = rtp->rt_brb.ri_brbw[1];
    1159:     rtp->rt_brb.ri_brbw[1] = i;
    1160:     if(rtp->rt_stat & RCI_BR) { /* previously replaced */
    1161:         rp_prev = 1;
    1162:         rp_orbn = rtp->rt_brb.ri_brbl;
    1163:     }
    1164:     rp_l = ra_drv[cn][unit].ra_trksz;   /* LBNs per track */
    1165:     rp_r = ra_drv[cn][unit].ra_rbns;    /* RBNs per track */
    1166:                         /* Primary RBN descriptor */
    1167:     rp_hblk = (((rp_lbn / rp_l) * rp_r) / 128) + 2;
    1168:     rp_hoff = ((rp_lbn / rp_l) * rp_r) % 128;
    1169:     rp_blk = (rp_rbn / 128) + 2;        /* Actual RBN descriptor */
    1170:     rp_off = rp_rbn % 128;
    1171:     if((rp_blk == rp_hblk) && (rp_off == rp_hoff))  /* Primary RBN ? */
    1172:         rp_pri = 1;
    1173:     else
    1174:         rp_sec = 1; /* YES, I know rp_sec not really used */
    1175:     if(rp_prev) {       /* set saved old RBN desc, as best we can */
    1176:         rp_orbd = rp_lbn;   /* LBN being replaced */
    1177:         rp_oblk = (rp_orbn / 128) + 2;
    1178:         rp_ooff = rp_orbn % 128;
    1179:         if((rp_oblk == rp_hblk) && (rp_ooff == rp_hoff))
    1180:             rp_orbd |= 04000000000; /* primary RBN */
    1181:         else
    1182:             rp_orbd |= 06000000000; /* non-primary RBN */
    1183:     }
    1184:     if(rctmcr(rp_blk, bp_rct1) < 0) {   /* First RCT block */
    1185:         rp_rcte(3, RD, rp_blk);
    1186:         goto rp_s18;
    1187:     }
    1188:     goto rp_s11;        /* finish up phase 2 */
    1189:
    1190: rp_s4:
    1191: #ifdef  DEBUG
    1192:     if(rp_bps == 4)
    1193:         goto do_u_x;
    1194: #endif	DEBUG
    1195: printf("4 ");
    1196: /*
    1197:  * Read the suspected bad block, remember whether or not the read succeeded.
    1198:  * Also, remember if the forced error indicator was set.
    1199:  */
    1200:     rp_irs = NO;
    1201:     p = bp_ir;
    1202:     for(i=0; i<512; i++)
    1203:         *p++ = 0;
    1204:     lseek(fd, (long)(rp_lbn*512), 0);
    1205:     ra_badc = RP_RD;
    1206:     for (i=0; i < 4; i++)
    1207:         if(read(fd, bp_ir, 512) == 512) {
    1208:             rp_irs = YES;
    1209:             break;
    1210:         }
    1211:         else {
    1212:             if(ra_stat[cn] & ST_DAT)
    1213:                 break;
    1214:             rp_irs = NO;
    1215:         }
    1216:
    1217:
    1218: rp_s5:
    1219: #ifdef  DEBUG
    1220:     if(rp_bps == 5)
    1221:         goto do_u_x;
    1222: #endif	DEBUG
    1223: printf("5 ");
    1224: /*
    1225:  * Save data read in step 4 in RCT block 1.
    1226:  */
    1227:     if(rctmcw(1, bp_ir) < 0) {
    1228:         rp_rcte(4, WRT, 1);
    1229:         goto rp_s18;
    1230:     }
    1231:
    1232: rp_s6:
    1233: #ifdef  DEBUG
    1234:     if(rp_bps == 6)
    1235:         goto do_u_x;
    1236: #endif	DEBUG
    1237: printf("6 ");
    1238: /*
    1239:  * Begin phase 1, save info in RCT block 0.
    1240:  */
    1241:     if(rctmcr(0, bp_rci) < 0) {
    1242:         rp_rcte(6, RD, 0);
    1243:         goto rp_s18;
    1244:     }
    1245:     rtp = (struct rct_rci *)bp_rci;
    1246:     rtp->rt_lbn.ri_lbnl = rp_lbn;
    1247:     i = rtp->rt_lbn.ri_lbnw[0]; /* reverse order */
    1248:     rtp->rt_lbn.ri_lbnw[0] = rtp->rt_lbn.ri_lbnw[1];
    1249:     rtp->rt_lbn.ri_lbnw[1] = i;
    1250:     rtp->rt_stat &= ~RCI_FE;
    1251:     if(rp_irs == NO)
    1252:         rtp->rt_stat |= RCI_FE;
    1253:     rtp->rt_stat |= RCI_P1;
    1254:     if(rctmcw(0, bp_rci) < 0) {
    1255:         rp_rcte(6, WRT, 0);
    1256:         goto rp_s17;
    1257:     }
    1258:
    1259: rp_s7:
    1260: #ifdef  DEBUG
    1261:     if(rp_bps == 7)
    1262:         goto do_u_x;
    1263: #endif	DEBUG
    1264: printf("7 ");
    1265: /*
    1266:  * Check to see if the block is really bad.
    1267:  *
    1268:  * Read the block, then write customer data, then write inverted
    1269:  * customer data.
    1270:  */
    1271:
    1272:     nondataerr = NO;
    1273:     rp_wcs7 = YES;
    1274:     if(rctmcr(1, bp_tmp) < 0) { /* Get best guess data from RCT blk 1 */
    1275:         rp_rcte(7, RD, 1);
    1276:         goto rp_s18;
    1277:     }
    1278:     for (i = 0; i < 4; i++) {
    1279:         /* check for any data error */
    1280:         lseek(fd, (long)(rp_lbn*512), 0);
    1281:         ra_badc = RP_AC;
    1282:         ra_badm = MD_SEC|MD_SREC;
    1283:         if ((read(fd, buf, 512) != 512)
    1284:             && ((ra_eflags[cn] & EF_BBR) || (ra_eflags[cn] & EF_BBU))
    1285:             || (ra_stat[cn]  & 0xe8)) {
    1286:             rp_wcs7 = NO;
    1287:             break;
    1288:         }
    1289:     }
    1290:     if (rp_wcs7 == NO && ((ra_stat[cn]  & 0xe8) != 0xe8)) {
    1291:         /* printf(" nondata read failure status = 0x%x - aborting\n",
    1292: 			ra_stat); GMM */
    1293:         rp_wcs7 = YES;
    1294:         nondataerr = YES;
    1295:     }
    1296:     if (rp_wcs7 == YES && ~nondataerr) {
    1297:         bp_tp = &buf[2048];
    1298:         bp_tmp = &buf[512];
    1299:         for (j= 0; j < 512; j++)
    1300:             *bp_tp++ = ~*bp_ir++;
    1301:         bp_tp = &buf[2048];
    1302:         bp_ir = &buf[512];
    1303:         for (i = 0; i < 8; i++) {
    1304:             if ((rp_wcs7 = blocktest(fd, !rp_irs, bp_ir)) == YES)
    1305:                 rp_wcs7 = blocktest(fd, 0, bp_tp);
    1306:             if (rp_wcs7 == NO)
    1307:                 break;
    1308:         }
    1309:     }
    1310:
    1311:
    1312: rp_s8:
    1313: #ifdef  DEBUG
    1314:     if(rp_bps == 8)
    1315:         goto do_u_x;
    1316: #endif	DEBUG
    1317: printf("8 ");
    1318: /*
    1319:  * Bad block may be good, write saved bad block contents back
    1320:  * out to bad block. May be a transient bad block error????
    1321:  *
    1322:  * NOTE: the "force" variable causes replacement regardless!
    1323:  */
    1324:     rp_wcs8 = YES;
    1325:     lseek(fd, (long)(rp_lbn*512), 0);
    1326:     ra_badc = RP_WRT;
    1327:     ra_badm = MD_CMP;
    1328:     if(rp_irs == NO)
    1329:         ra_badm |= MD_ERR;
    1330:     if(write(fd, (char *)bp_ir, 512) == 512) {
    1331:         if(((ra_eflags[cn] & EF_BBR) == 0) &&
    1332:             (rp_irs == YES)) {
    1333:             if(force || (rp_wcs7 == NO))
    1334:                 goto rp_s9;
    1335:             else
    1336:                 goto rp_s13;
    1337:         }
    1338:     }
    1339:     if((ra_stat[cn] & 0xe8) &&  /* DATA ERROR with FORCED ERROR */
    1340:        (rp_irs == NO) &&
    1341:        ((ra_eflags[cn] & EF_BBR) == 0))
    1342:             if(force)
    1343:                 goto rp_s9;
    1344:             else
    1345:                 goto rp_s13;
    1346:
    1347: rp_s9:
    1348: #ifdef  DEBUG
    1349:     if(rp_bps == 9)
    1350:         goto do_u_x;
    1351: #endif	DEBUG
    1352: printf("9 ");
    1353: /*
    1354:  * Seach the RCT for the replacement block number (RBN) and
    1355:  * whether or not the bad LBN was previously replaced, if so
    1356:  * also get the old RBN.
    1357:  */
    1358: /* Set initial (hash) RCT block # and offset, init variables */
    1359:
    1360:     if (bbr_recur >= 2) {
    1361:         printf("Replacement Command Failure at LBN %d\n", rp_lbn);
    1362:         goto rp_s16;
    1363:     }
    1364:     else
    1365:         bbr_recur++;
    1366:     firstblk = 0;
    1367:     rp_prev = rp_pri = rp_sec = 0;
    1368:     rp_l = ra_drv[cn][unit].ra_trksz;   /* LBNs per track */
    1369:     rp_r = ra_drv[cn][unit].ra_rbns;    /* RBNs per track */
    1370:     rp_hblk = (((rp_lbn / rp_l) * rp_r) / 128) + 2;
    1371:     rp_hoff = ((rp_lbn / rp_l) * rp_r) % 128;
    1372:     rp_blk = rp_hblk;
    1373:     rp_off = rp_hoff;
    1374: /* Check for primary RBN descriptor empty or matches this LBN */
    1375:
    1376:     if(rctmcr(rp_blk, bp_rct1) < 0) {
    1377:         rp_rcte(9, RD, rp_blk);
    1378:         goto rp_s16;
    1379:     }
    1380:     if(rbempty()) {
    1381:         rp_pri++;
    1382:         goto rp_s9_f;   /* found RBN */
    1383:     }
    1384:     if(rbmatch()) {
    1385:         rp_prev++;
    1386:         rp_orbn = ((rp_blk - 2) * 128) + rp_off;
    1387: /* OLDCODE	rp_orbn = bp_rct1[rp_off].rbnd_l & ~036000000000;	*/
    1388:         rp_orbd = bp_rct1[rp_off].rbnd_l;
    1389:     }
    1390: /* Start ping-pong search */
    1391:
    1392:
    1393:     first_level = YES;
    1394:     off_bottom = off_top = NO;
    1395:     rp_delta = 1;
    1396:     do {
    1397:         rp_off = rp_hoff + rp_delta;
    1398:         if((rp_off >= 0) && (rp_off <= 127) && !rbnull()) {
    1399:             if(rbempty()) {
    1400:                 rp_sec++;
    1401:                 goto rp_s9_f;       /* found RBN */
    1402:             }
    1403:             if(rbmatch()) {
    1404:                 rp_prev++;
    1405:                 rp_orbn = ((rp_blk - 2) * 128) + rp_off;
    1406:                 rp_orbd = bp_rct1[rp_off].rbnd_l;
    1407:             }
    1408:         }
    1409:         else {
    1410:             if(rp_off > 127)
    1411:                 off_bottom = YES;
    1412:             if(rp_off < 0)
    1413:                 off_top = YES;
    1414:             if((off_top = YES) && (off_top == off_bottom))
    1415:                 first_level == NO;
    1416:         }
    1417:         rp_delta = -rp_delta;
    1418:         if(rp_delta >= 0)
    1419:             rp_delta++;
    1420:     }
    1421:     while ((first_level) && (!rbnull()));
    1422:     if(!rbnull())
    1423:         rp_blk++;
    1424:     else
    1425:         rp_blk = 2;
    1426:     firstblk++;
    1427:     rp_off = rp_hoff = 0;
    1428:
    1429: /* Start of linear search */
    1430:
    1431: rp_s9_l:
    1432:     if(rblast()) {  /* If primary in last RCT block, go to first block */
    1433:         rp_blk = 2;
    1434:         rp_off = 0;
    1435:     }
    1436: rp_s9_l1:
    1437:     if(rctmcr(rp_blk, bp_rct1) < 0) {
    1438:         rp_rcte(9, RD, rp_blk);
    1439:         goto rp_s16;
    1440:     }
    1441:     rp_off = 0;
    1442: rp_s9_l2:
    1443:     if((rp_blk == rp_hblk) && (!firstblk )) {  /* search failed */
    1444:         rp_rcte(9, -1, 0);  /* RP step 9 FAILED! - message */
    1445:         printf("\nRCT search failed: no replacement block available!\n");
    1446:         goto rp_s16;
    1447:     }
    1448:     if(rbempty()) {
    1449:         rp_sec++;
    1450:         goto rp_s9_f;       /* found RBN */
    1451:     }
    1452:     if(rbmatch()) {
    1453:         rp_prev++;
    1454:         rp_orbn = ((rp_blk - 2) * 128) + rp_off;
    1455: /* OLDCODE	rp_orbn = bp_rct1[rp_off].rbnd_l & ~036000000000;	*/
    1456:         rp_orbd = bp_rct1[rp_off].rbnd_l;
    1457:     }
    1458:     if(rbnull()) {
    1459:         rp_blk = 2;
    1460:         goto rp_s9_l1;
    1461:     }
    1462:     rp_off++;
    1463:     if(rp_off > 127) {
    1464:         rp_blk++;
    1465:         firstblk = 0;
    1466:         goto rp_s9_l1;
    1467:     }
    1468:     goto rp_s9_l2;
    1469: rp_s9_f:
    1470:     rp_rbn = ((rp_blk - 2) * 128) + rp_off;
    1471: rp_s10:
    1472: #ifdef  DEBUG
    1473:     if(rp_bps == 10)
    1474:         goto do_u_x;
    1475: #endif	DEBUG
    1476: /*
    1477:  * Update RCT block 0 with RBN, BR flag, and say in phase 2.
    1478:  */
    1479: printf("10 ");
    1480:     rtp->rt_rbn.ri_rbnl = rp_rbn;
    1481:     i = rtp->rt_rbn.ri_rbnw[0]; /* reverse order */
    1482:     rtp->rt_rbn.ri_rbnw[0] = rtp->rt_rbn.ri_rbnw[1];
    1483:     rtp->rt_rbn.ri_rbnw[1] = i;
    1484:     if(rp_prev) {
    1485:         rtp->rt_brb.ri_brbl = rp_orbn;
    1486:         i = rtp->rt_brb.ri_brbw[0]; /* reverse order */
    1487:         rtp->rt_brb.ri_brbw[0] = rtp->rt_brb.ri_brbw[1];
    1488:         rtp->rt_brb.ri_brbw[1] = i;
    1489:         rtp->rt_stat |= RCI_BR;
    1490:     }
    1491:     rtp->rt_stat &= ~RCI_P1;
    1492:     rtp->rt_stat |= RCI_P2;
    1493:     if(rctmcw(0, bp_rci) < 0) {
    1494:         rp_rcte(10, WRT, 0);
    1495:         goto rp_s16;
    1496:     }
    1497:
    1498: rp_s11:
    1499: #ifdef  DEBUG
    1500:     if(rp_bps == 11)
    1501:         goto do_u_x;
    1502: #endif	DEBUG
    1503: /*
    1504:  * Update RCT to say block has been replaced.
    1505:  */
    1506: printf("11 ");
    1507:     bp_rct1[rp_off].rbnd_l = rp_lbn;
    1508:     if(rp_pri)
    1509:         bp_rct1[rp_off].rbnd_w[0] |= 020000;
    1510:     else
    1511:         bp_rct1[rp_off].rbnd_w[0] |= 030000;
    1512:     rp_oblk = (rp_orbn / 128) + 2;
    1513:     rp_ooff = rp_orbn % 128;
    1514:     if(rp_prev) {
    1515:         if(rp_blk != rp_oblk) { /* rbn & old rbn in diff blks */
    1516:             if(rctmcr(rp_oblk, bp_rct2) < 0) {
    1517:                 rp_rcte(11, RD, rp_oblk);
    1518:                 goto rp_s16;
    1519:             }
    1520:             bp_rct2[rp_ooff].rbnd_l = 010000000000L;
    1521:         } else
    1522:             bp_rct1[rp_ooff].rbnd_l = 010000000000L;
    1523:     }
    1524:     if(rctmcw(rp_blk, bp_rct1) < 0) {
    1525:         rp_rcte(11, WRT, rp_blk);
    1526:         goto rp_s15;
    1527:     }
    1528:     if(rp_prev && (rp_oblk != rp_blk)) {
    1529:         if(rctmcw(rp_blk, bp_rct2) < 0) {
    1530:             rp_rcte(11, WRT, rp_blk);
    1531:             goto rp_s15;
    1532:         }
    1533:     }
    1534:
    1535: rp_s12:
    1536: #ifdef  DEBUG
    1537:     if(rp_bps == 12)
    1538:         goto do_u_x;
    1539: #endif	DEBUG
    1540: /*
    1541:  * Use the REPLACE command to cause the controller
    1542:  * to replace the bad block.
    1543:  */
    1544: printf("12 ");
    1545:     lseek(fd, (long)(rp_lbn*512), 0);
    1546:     ra_badc = RP_REP;
    1547:     if(rp_pri)
    1548:         ra_badm = MD_PRI;
    1549:     ra_rbn.ra_rbnl = rp_rbn;    /* tell driver replacement block # */
    1550:     write(fd, (char *)bp_ir, 512);  /* really a REPLACE command */
    1551:     if((ra_stat[cn] & ST_MSK) != ST_SUC) {
    1552:         rp_rcte(12, -1, 0); /* RP step 12 FAILED! - message */
    1553:         printf("\nMSCP replace command failed!\n");
    1554:         goto rp_s17;
    1555:     }
    1556:     if(rp_dirty == 2) goto rp_s120;
    1557:     /*
    1558: 	 * First, read the block and check for the Forced Error flag.
    1559: 	 * All unused RBNs are written with the forced error flag, so
    1560: 	 * it should be set if the replace command worked.
    1561: 	 */
    1562:     lseek(fd, (long)(rp_lbn*512), 0);
    1563:     ra_badc = RP_RD;
    1564:     read(fd, buf, 512);
    1565:     if ((ra_stat[cn] & ST_DAT) != ST_DAT) {
    1566:         rp_rcte(12, -1, 0); /* RP step 12 FAILED! - message */
    1567:         printf("\nMSCP replace command failed!\n");
    1568:         printf("RBN used for LBN %d did not contain Forced Error indicator.\n", rp_lbn);
    1569:         /*printd2("ra_stat = 0x%x, ra_ecode = 0x%x, ra_eflags = 0x%x\n",
    1570: 			ra_stat, ra_ecode, ra_eflags); */
    1571:         goto rp_s17;
    1572:     }
    1573:     /*
    1574: 	 * Read the date to be written to the replacement block
    1575: 	 * from RCT block 1 -- just to be safe.
    1576: 	 */
    1577:     /* if (rctmcr(1, bp_ir) < 0) {
    1578: 		rp_rcte(12, RD, 0);
    1579: 		goto rp_s18;
    1580: 	} */
    1581: rp_s120:
    1582:     lseek(fd, (long)(rp_lbn*512), 0);
    1583:     ra_badc = RP_WRT;
    1584:     ra_badm = MD_CMP;
    1585:     if(rp_irs == NO)
    1586:         ra_badm |= MD_ERR;
    1587:     write(fd, (char *)bp_ir, 512);  /* write saved -> replacement block */
    1588:     if((ra_stat[cn] & ST_MSK) == ST_SUC)
    1589:         goto rp_s121;
    1590:     if((ra_eflags[cn] & EF_BBR) != EF_BBR)
    1591:         if((ra_stat[cn] == ST_DAT) && (rp_irs == NO))
    1592:             goto rp_s121;
    1593:     /* write - compare failed */
    1594:     rp_rcte(12, -1, 0);
    1595:     printf("\nWRITE-COMPARE operation on replacement block failed!\n");
    1596:     /*
    1597: 	 *  If a header compare error or a bad block reported, go back
    1598: 	 *  to step 9 and try to find another RBN.
    1599: 	 */
    1600:     if((ra_stat[cn] != MD_HCE) || (ra_eflags[cn] & EF_BBR))
    1601:         goto rp_s9;
    1602:     else {
    1603:         printf("Check the RCT, it MAY be corrupt!!\n");
    1604:         if(cmd[0] = 'i')
    1605:             goto bg_loop;
    1606:         else {
    1607:             goto do_u_x;
    1608:         }
    1609:     }
    1610: rp_s121:    /* replacement succeeded */
    1611:     rp_didit++;
    1612:
    1613: rp_s13:
    1614: #ifdef  DEBUG
    1615:     if(rp_bps == 13)
    1616:         goto do_u_x;
    1617: #endif	DEBUG
    1618: /*
    1619:  * Update RCT block 0 to indicate replacement
    1620:  * no longer in progress.
    1621:  */
    1622: printf("13 ");
    1623:     rtp->rt_stat &= RCI_VP; /* clean out all but VP */
    1624:     rtp->rt_lbn.ri_lbnl = 0L;
    1625:     rtp->rt_rbn.ri_rbnl = 0L;
    1626:     rtp->rt_brb.ri_brbl = 0L;
    1627:     if(rctmcw(0, bp_rci) < 0) {
    1628:         rp_rcte(13, WRT, 0);
    1629:         goto rp_s17;
    1630:     }
    1631:
    1632: rp_s14:
    1633: #ifdef  DEBUG
    1634:     if(rp_bps == 14)
    1635:         goto do_u_x;
    1636: #endif	DEBUG
    1637: /*
    1638:  * Soft lock not used.
    1639:  * Replacement completed, return!
    1640:  */
    1641:     if(cmd[0] == 'i') {
    1642:         if(rp_didit)
    1643:             goto do_i_rg;
    1644:         else
    1645:             goto do_i_ra;
    1646:     } else {
    1647:         if(fd > 0)
    1648:             close(fd);
    1649:         if(rp_dirty)
    1650:             rp_dirty = 0;
    1651:         if(rp_didit)
    1652:             printf("SUCCEEDED!\n");
    1653:         else
    1654:             if (nondataerr) {
    1655:                 printf("ABORTED (nondata error encontered)!\n");
    1656:                 nondataerr = NO;
    1657:             }
    1658:             else
    1659:                 printf("ABORTED (block not really bad)!\n");
    1660:         goto retry;
    1661:     }
    1662:
    1663: rp_s15:
    1664: #ifdef  DEBUG
    1665:     if(rp_bps == 15)
    1666:         goto do_u_x;
    1667: #endif	DEBUG
    1668: /*
    1669:  * Restore RCT to say new RBN unusable and
    1670:  * set bad LBN back to its original state.
    1671:  * ECO: not sure what to do yet!
    1672:  *	For now, say RBN unusable regardless!
    1673:  */
    1674: printf("15 ");
    1675:     bp_rct1[rp_off].rbnd_l = 010000000000L;
    1676:     if(rp_prev) {
    1677:         if(rp_blk != rp_oblk)
    1678:             bp_rct2[rp_ooff].rbnd_l = rp_orbd;
    1679:         else
    1680:             bp_rct1[rp_ooff].rbnd_l = rp_orbd;
    1681:     }
    1682:     if(rctmcw(rp_blk, bp_rct1) < 0)
    1683:         rp_rcte(15, WRT, rp_blk);
    1684:     if(rp_prev && (rp_blk != rp_oblk))
    1685:         if(rctmcw(rp_oblk, bp_rct2) < 0)
    1686:             rp_rcte(15, WRT, rp_oblk);
    1687:
    1688: rp_s16:
    1689: #ifdef  DEBUG
    1690:     if(rp_bps == 16)
    1691:         goto do_u_x;
    1692: #endif	DEBUG
    1693: /*
    1694:  * Write saved date back to the bad LBN
    1695:  * with forced error modifier.
    1696:  */
    1697: printf("16 ");
    1698:     lseek(fd, (long)(rp_lbn*512), 0);
    1699:     ra_badc = RP_WRT;
    1700:     if(rp_irs == NO)
    1701:         ra_badm = MD_ERR;
    1702:     if(write(fd, (char *)bp_ir, 512) != 512) {
    1703:         rp_rcte(16, -1, 0); /* RP step 16 FAILED! - message */
    1704:         printf("\nRewrite of original data back to bad block failed!\n");
    1705:     }
    1706:
    1707: rp_s17:
    1708: #ifdef  DEBUG
    1709:     if(rp_bps == 17)
    1710:         goto do_u_x;
    1711: #endif	DEBUG
    1712: /*
    1713:  * Update RCT block 0 to say replacement
    1714:  * no longer inprogress.
    1715:  */
    1716: printf("17 ");
    1717:     rtp->rt_stat &= RCI_VP; /* clean out all but VP */
    1718:     rtp->rt_lbn.ri_lbnl = 0L;
    1719:     rtp->rt_rbn.ri_rbnl = 0L;
    1720:     rtp->rt_brb.ri_brbl = 0L;
    1721:     if(rctmcw(0, bp_rci) < 0)
    1722:         rp_rcte(17, WRT, 0);
    1723:
    1724: rp_s18:
    1725: #ifdef  DEBUG
    1726:     if(rp_bps == 18)
    1727:         goto do_u_x;
    1728: #endif	DEBUG
    1729: /*
    1730:  * Soft lock not used.
    1731:  * Replacement failed, return!
    1732:  */
    1733:     if(cmd[0] == 'i')
    1734:         goto do_i_rb;
    1735:     else {
    1736:         if(rp_dirty)
    1737:             rp_dirty = 0;
    1738:         printf("\n\7\7\7Block %D replacement FAILED!\n", rp_lbn);
    1739:         if(fd > 0)
    1740:             close(fd);
    1741:         goto retry;
    1742:     }
    1743: }
    1744:
    1745: /*
    1746:  *  Write data to a block, and then read it -- thus testing the block
    1747:  */
    1748:
    1749: blocktest(fd, ucerr, bp)
    1750: int fd;         /* file descriptor */
    1751: char    *bp;
    1752: int ucerr;          /* uncorrectable ECC error when reading
    1753: 				 * the block the block to be replaced
    1754: 				 */
    1755: {
    1756:     int i, count;
    1757:     int block_good; /* true if block is thought to be good */
    1758:
    1759:     block_good = YES;
    1760:     lseek(fd, (long)(rp_lbn*512), 0);
    1761:     ra_badc = RP_WRT;
    1762:     ra_badm = (MD_CMP|MD_SEC|MD_SREC | (!ucerr ? 0 : MD_ERR));
    1763:     if((((count = write(fd, bp, 512)) != 512) && (ra_eflags[cn] & EF_BBR)) ||
    1764:         (ra_stat[cn] & 0xe8)) {
    1765:         block_good = NO;
    1766:     }
    1767:     if (block_good == YES) {
    1768:         for (i = 0; i < 4; i++) {
    1769:             lseek(fd, (long)(rp_lbn*512), 0);
    1770:             ra_badc = RP_AC;
    1771:             ra_badm = MD_SEC|MD_SREC;
    1772:             if(((read(fd, buf, 512) != 512) && (ra_eflags[cn] & EF_BBR)) ||
    1773:                 (ra_stat[cn] & 0xe8)) {
    1774:                 block_good = NO;
    1775:                 break;
    1776:             }
    1777:         }
    1778:     }
    1779:     return (block_good);
    1780: }
    1781: /*
    1782:  * RCT read/write fatal error message
    1783:  *
    1784:  * s	= step in replacement process
    1785:  * rw	= failure was on read or write
    1786:  *	= -1, print first line then return
    1787:  * lbn	= block number
    1788:  */
    1789:
    1790: rp_rcte(s, rw, lbn)
    1791: int s;
    1792: int rw;
    1793: int lbn;
    1794: {
    1795:     printf("\n\7\7\7Bad block replacement process step %d FAILED!", s);
    1796:     if(rw == -1)
    1797:         return;
    1798:     printf("\nMulticopy %s", (rw == WRT) ? "write" : "read");
    1799:     printf(" of RCT block %d FAILED!\n", lbn);
    1800:     deprnt();   /* print disk error info */
    1801: }
    1802:
    1803: /*
    1804:  * Open the disk and set file descriptor in fd.
    1805:  * mode = how to open, read, write, read/write.
    1806:  * err  = ignore errors (see if drive is there).
    1807:  *
    1808:  * If the disk has an RCT, read RCT block zero
    1809:  * and set rp_dirty to the phase that was in
    1810:  * progress if the replacement was interrupted.
    1811:  * Otherwise, set rp_dirty to zero.
    1812:  */
    1813: dskopen(err, mode)
    1814: int err;
    1815: int mode;
    1816: {
    1817:     register struct rct_rci *rtp;
    1818:
    1819:     if((fd = open(fn, mode)) <= 0) {
    1820:         if(err == 0) {
    1821:             printf("\nCan't open %s!\n", fn);
    1822:             exit(FATAL);
    1823:         }
    1824:         return;
    1825:     }
    1826:     rp_dirty = 0;
    1827:     if((ra_drv[cn][unit].ra_rctsz == 0) || (dip->di_flag != BB_COOP))
    1828:         return;
    1829:     if(rctmcr(0, bp_rci) < 0) {
    1830:         printf("\n\7\7\7WARNING: cannot read RCT block zero for ");
    1831:         printf("%s unit %d!\n", ra_dct[cn], unit);
    1832:         return;
    1833:     }
    1834:     rtp = (struct rct_rci *)bp_rci;
    1835:     if(rtp->rt_stat & RCI_P1)
    1836:         rp_dirty = 1;
    1837:     if(rtp->rt_stat & RCI_P2)
    1838:         rp_dirty = 2;
    1839:     if(rp_dirty == 0)
    1840:         return;
    1841:     printf("\n\7\7\7\t\t****** WARNING ******\n");
    1842:     printf("\nA bad block replacement was interrupted during phase %d.\n",
    1843:         rp_dirty);
    1844:     if(cmd[0] == 'r')
    1845:         return;
    1846:     printf("\nAfter the current command completes, execute a replace");
    1847:     printf("\ncommand by responding to the rabads < ..... >: prompt");
    1848:     printf("\nwith the letter r followed by <RETURN>. This will");
    1849:     printf("\ncause the interrupted replacement of be completed.\n");
    1850: }
    1851:
    1852: prtdsk()
    1853: {
    1854:     struct dkinfo *dp;
    1855:
    1856:     printf("\nDisk\tULTRIX\tSize in");
    1857:     printf("\nName\tName\tBlocks");
    1858:     printf("\n----\t----\t------");
    1859:     for(dp=dkinfo; dp->di_type; dp++){
    1860:         printf("\n%s\t", dp->di_type);
    1861:         printf("%s\t", dp->di_name);
    1862:         printf("%D", dp->di_size);
    1863:     }
    1864:     printf("\n");
    1865: }
    1866: /*
    1867:  * Drive information pointer set,
    1868:  *	pointer into dkinfo table,
    1869:  *	unit number,
    1870:  *	MSCP controller number,
    1871:  *	file name - ??(#,0).
    1872:  */
    1873: dipset()
    1874: {
    1875:     register int i;
    1876:
    1877:     printf("\nDisk type < ");
    1878:     for(i=0; dkinfo[i].di_type; i++) {
    1879:         printf("%s ", dkinfo[i].di_type);
    1880:     }
    1881:     printf(">: ");
    1882:     gets(dt);
    1883:     for(dip=dkinfo; dip->di_type; dip++)
    1884:         if(strcmp(dip->di_type, dt) == 0)
    1885:             break;
    1886:     if(dip->di_type == 0) {
    1887:         printf("\n(%s) - not supported by RABADS!\n", dt);
    1888: dip_x:
    1889:         if(argflag)
    1890:             exit(FATAL);
    1891:         else
    1892:             return(-1);
    1893:     }
    1894:     printf("\nUnit number < 0-3 >: ");
    1895:     gets(dn);
    1896:     if((strlen(dn) != 1) || (dn[0] < '0') || (dn[0] > '3')) {
    1897:         printf("\nUnits 0 -> 3 only!\n");
    1898:         goto dip_x;
    1899:     }
    1900:     unit = dn[0] - '0';
    1901:     sprintf(fn, "%s(%s,0)", dip->di_name, dn);
    1902:     for(i=0; devsw[i].dv_name; i++)
    1903:         if(strcmp(dip->di_name, devsw[i].dv_name) == 0)
    1904:             break;
    1905:     cn = devsw[i].dv_cn;
    1906: #ifdef  DEBUG
    1907:
    1908:     printf("\nDEBUG: Break Point at replacement step ? ");
    1909:     gets(line);
    1910:     if(line[0] == '\0')
    1911:         rp_bps = 0;
    1912:     else
    1913:         rp_bps = atoi(line);
    1914:
    1915: #endif	DEBUG
    1916:     return(0);
    1917: }
    1918:
    1919: /*
    1920:  * RCT multicopy read,
    1921:  *	lbn = sector of RCT to read.
    1922:  *	bp = pointer to buffer.
    1923:  *	Host area size is added to lbn.
    1924:  * cn is MSCP cntlr number, unit is drive number,
    1925:  * fd is the previously opened file descriptor,
    1926:  * all are external to main().
    1927:  */
    1928:
    1929: rctmcr(lbn, bp)
    1930: unsigned lbn;
    1931: union rctb *bp;
    1932: {
    1933:     register int i, n, s;
    1934:     daddr_t bn, boff;
    1935:
    1936:     n = ra_drv[cn][unit].ra_ncopy;
    1937:     s = ra_drv[cn][unit].ra_rctsz;
    1938:     bn = ra_drv[cn][unit].d_un.ra_dsize + lbn;
    1939:     for(i=0; i<n; i++) {
    1940:         if(rctcopy && (rctcopy != (i+1)))
    1941:             continue;
    1942:         boff = bn * 512;
    1943:         lseek(fd, (long)boff, 0);
    1944:         ra_badc = RP_RD;    /* tell driver doing BADS funny business */
    1945:         read(fd, (char *)bp, 512);
    1946:         if(ra_stat[cn] == ST_SUC) {
    1947:             if(lbn > 1)
    1948:                 rctrev(bp);
    1949:             return(0);
    1950:         }
    1951:         bn += s;
    1952:     }
    1953:     return(-1);
    1954: }
    1955:
    1956: /*
    1957:  * RCT multicopy write,
    1958:  *	lbn = sector of RCT to write.
    1959:  *	bp = pointer to buffer.
    1960:  *	Host area size is added to lbn.
    1961:  * cn is the MSCP cntlr number, unit is drive number,
    1962:  * fd is the previously opened file descriptor,
    1963:  * all are external to main().
    1964:  */
    1965:
    1966: rctmcw(lbn, bp)
    1967: unsigned lbn;
    1968: union rctb *bp;
    1969: {
    1970:     register int i, n, s;
    1971:     int ec, sc, fatal;
    1972:     daddr_t bn, boff;
    1973:
    1974:     n = ra_drv[cn][unit].ra_ncopy;
    1975:     s = ra_drv[cn][unit].ra_rctsz;
    1976:     bn = ra_drv[cn][unit].d_un.ra_dsize + lbn;
    1977:     ec = fatal = 0;
    1978:     if(lbn > 1)     /* only reverse blocks containing RBNs */
    1979:         rctrev(bp);
    1980:     for(i=0; i<n; i++, bn += s) {
    1981:         boff = bn * 512;
    1982:         lseek(fd, (long)boff, 0);
    1983:         ra_badc = RP_WRT;   /* tells driver doing BADS funny business */
    1984:         ra_badm = MD_CMP;
    1985:         write(fd, (char *)bp, 512);
    1986:         if(ra_stat[cn] == ST_SUC)
    1987:             continue;
    1988:         sc = (ra_stat[cn] >> 5) & 03777;
    1989:         if((ra_stat[cn] & ST_MSK) == ST_DAT) {
    1990:             if((sc != 2) && (sc != 3) && (sc != 7))
    1991:                 continue; /* NOT - HCE, DATA SYNC, UNC ECC */
    1992:             ec++;
    1993:             lseek(fd, (long)boff, 0);
    1994:             ra_badc = RP_WRT;
    1995:             ra_badm = MD_ERR;
    1996:             write(fd, (char *)bp, 512);
    1997:             if((ra_stat[cn] & ST_MSK) == ST_SUC)
    1998:                 continue;
    1999:             sc = (ra_stat[cn] >> 5) & 03777;
    2000:             if((ra_stat[cn] & ST_MSK) == ST_DAT) {
    2001:                 if((sc != 2) && (sc != 3) && (sc != 7))
    2002:                     continue;
    2003:             }
    2004:         }
    2005:         fatal = -1;
    2006:         break;
    2007:     }
    2008:     if(ec >= n)
    2009:         fatal = -1;
    2010:     return(fatal);
    2011: }
    2012:
    2013: /*
    2014:  * Reverse the order of the RBN descriptors in bp_rct1[].
    2015:  * ULTRIX-11 C still need hi order word first!
    2016:  */
    2017:
    2018: rctrev(bp)
    2019: union rctb *bp;
    2020: {
    2021:     register union rctb *rbp;
    2022:     register int i, j;
    2023:
    2024:     rbp = bp;
    2025:     for(i=0; i<128; i++) {
    2026:         j = rbp[i].rbnd_w[0];
    2027:         rbp[i].rbnd_w[0] = rbp[i].rbnd_w[1];
    2028:         rbp[i].rbnd_w[1] = j;
    2029:     }
    2030: }
    2031:
    2032: /*
    2033:  * Print the disk error information that would
    2034:  * have been printed by the driver if the ra_badc
    2035:  * flag was not set.
    2036:  */
    2037: deprnt()
    2038: {
    2039:     printf("%s unit %d disk error: ",
    2040:         ra_dct[cn], unit);
    2041:     printf("endcode=%o flags=%o status=%o\n",
    2042:         ra_ecode[cn], ra_eflags[cn], ra_stat[cn]);
    2043:     printf("(FATAL ERROR)\n");
    2044: }
    2045:
    2046: rbempty()
    2047: {
    2048:     if((bp_rct1[rp_off].rbnd_l & 036000000000) == 0)
    2049:         return(1);
    2050:     else
    2051:         return(0);
    2052: }
    2053:
    2054: rbmatch()
    2055: {
    2056:     if((bp_rct1[rp_off].rbnd_l & 04000000000) == 0)
    2057:         return(0);
    2058:     if(rp_lbn == (bp_rct1[rp_off].rbnd_l & ~036000000000))
    2059:         return(1);
    2060:     return(0);
    2061: }
    2062:
    2063: rbnull()
    2064: {
    2065:     if((bp_rct1[rp_off].rbnd_l & 036000000000) == 020000000000)
    2066:         return(1);
    2067:     else
    2068:         return(0);
    2069: }
    2070: rblast()
    2071: {
    2072:     register int i;
    2073:
    2074:     for(i=0; i<128; i++)
    2075:         if((bp_rct1[i].rbnd_l & 036000000000) == 020000000000)
    2076:             return(1);
    2077:     return(0);
    2078: }
    2079:
    2080: prfm()
    2081: {
    2082:     register char c;
    2083:
    2084:     printf("\n\nPress <RETURN> for more");
    2085:     printf(" (<CTRL/C> to abort): ");
    2086:     while((c=getchar()) != '\n') {
    2087:         if(c == 03) /* <CTRL/C> */
    2088:             return(1);
    2089:     }
    2090:     return(0);
    2091: }
    2092:
    2093: char    ynline[40];
    2094:
    2095: yes(hlp)
    2096: {
    2097: yorn:
    2098:     gets(ynline);
    2099:     if((strcmp(ynline, "y") == 0) || (strcmp(ynline, "yes") == 0))
    2100:         return(YES);
    2101:     if((strcmp(ynline, "n") == 0) || (strcmp(ynline, "no") == 0))
    2102:         return(NO);
    2103:     if(hlp)
    2104:         if((strcmp(ynline, "?") == 0) || (strcmp(ynline, "help") == 0))
    2105:         return(HELP);
    2106:     printf("\nPlease answer yes or no!\n");
    2107:     goto yorn;
    2108: }
    2109:
    2110: /*
    2111:  * Read a suspected bad block and
    2112:  * return its status.
    2113:  */
    2114:
    2115: brchk(lbn)
    2116: daddr_t lbn;
    2117: {
    2118:     register int i, s;
    2119:
    2120:     for(i=0; i<100; i++) {
    2121:         lseek(fd, (long)(lbn*512), 0);
    2122:         ra_badc = RP_AC;
    2123:         if(read(fd, (char *)&buf, 512) != 512)
    2124:             break;
    2125:     }
    2126:     s = ra_stat[cn] & ST_MSK;
    2127:     if(s == ST_SUC) {
    2128:         if(ra_eflags[cn] & EF_BBR)
    2129:             return(BR_BBR);
    2130:         else
    2131:             return(BR_NBBR);
    2132:     } else if(s == ST_DAT) {
    2133:         if((dip->di_flag != BB_RWRT) && (ra_eflags[cn] & EF_BBR))
    2134:             return(BR_DEB);
    2135:         switch((ra_stat[cn] >> 5) & 03777) {
    2136:         case 0:
    2137:             return(BR_FEM);
    2138:         case 4:
    2139:         case 8:
    2140:         case 9:
    2141:         case 10:
    2142:         case 11:
    2143:         case 12:
    2144:         case 13:
    2145:         case 14:
    2146:         case 15:
    2147:             /* can't happen - not allowing datagrams */
    2148:             return(BR_CECC);
    2149:         case 7:
    2150:             return(BR_UECC);
    2151:         default:
    2152:             return(BR_NDE);
    2153:         }
    2154:     } else
    2155:         return(BR_NDE);
    2156: }
    2157:
    2158: /*
    2159:  * Conditionally print BLOCK # header message.
    2160:  * Rewite a block that was written with "forced error".
    2161:  * Return status of rewrite operation.
    2162:  */
    2163:
    2164: fembrw(hm, lbn)
    2165: int hm;
    2166: daddr_t lbn;
    2167: {
    2168:     if(hm)
    2169:         printf("BLOCK: %D - ", lbn);
    2170:     printf("rewrite to clear \"forced error\" ");
    2171:     lseek(fd, (long)(lbn*512), 0);
    2172:     ra_badc = RP_WRT;
    2173:     write(fd, (char *)&buf, 512);
    2174:     lseek(fd, (long)(lbn*512), 0);
    2175:     if(read(fd, (char *)&buf, 512) == 512) {
    2176:         printf("SUCCEEDED!\n");
    2177:         return(YES);
    2178:     } else {
    2179:         printf("FAILED!\n");
    2180:         deprnt();   /* print disk error info */
    2181:         return(NO);
    2182:     }
    2183: }

#### Defined functions

blocktest defined in line 1749; used 2 times

- in line 1304-1305(2)

brchk defined in line 2115; used 3 times

- in line 582, 949, 1014

deprnt defined in line 2037; used 9 times

- in line 943, 970, 980, 1009, 1035, 1047, 1061, 1800, 2180

dipset defined in line 1873; used 5 times

- in line 395, 550, 656, 692, 825

dskopen defined in line 1813; used 5 times

- in line 397, 557, 663, 694, 827

fembrw defined in line 2164; used 5 times

- in line 936, 960, 1003, 1029, 1055

main defined in line 340; never used
prfm defined in line 2080; used 3 times

- in line 749-753(2), 768

prtdsk defined in line 1852; used 1 times

- in line 372

rbempty defined in line 2046; used 3 times

- in line 1380, 1399, 1448

rblast defined in line 2070; used 1 times

- in line 1432

rbmatch defined in line 2054; used 3 times

- in line 1384, 1403, 1452

rbnull defined in line 2063; used 4 times

- in line 1398, 1421-1422(2), 1458

rctmcr defined in line 1929; used 12 times

- in line 715, 740, 758, 1127-1131(2), 1184, 1241, 1274, 1376, 1437, 1516, 1829

rctmcw defined in line 1966; used 9 times

- in line 1227, 1254, 1493, 1524-1529(2), 1627, 1682-1685(2), 1721

rctrev defined in line 2018; used 2 times

- in line 1948, 1979

rp_rcte defined in line 1790; used 22 times

- in line 1128-1132(2), 1185, 1228, 1242, 1255, 1275, 1377, 1438, 1444, 1494, 1517, 1525-1530(2), 1552, 1566, 1594, 1628, 1683-1686(2), 1703, 1722

yes defined in line 2095; used 3 times

- in line 600, 617, 867

#### Defined variables

allflag defined in line 254; used 6 times

- in line 358, 378-381(2), 704, 783, 792

ask defined in line 253; used 5 times

- in line 356, 380, 748-752(2), 767

badcnt defined in line 251; used 9 times

- in line 877, 899-902(2), 908, 921, 937, 994, 1004, 1056

bbr_recur defined in line 270; used 3 times

- in line 1105, 1360-1365(2)

bdwarn defined in line 322; used 1 times

- in line 903

bn defined in line 250; used 30 times

- in line 573-582(6), 619, 625, 643-645(2), 681-686(5), 879-893(5), 915(2), 1934-1942(3), 1951, 1972-1981(4)

bp_ir defined in line 182; used 13 times

- in line 740, 746, 1131, 1201, 1207, 1227, 1300-1304(3), 1330, 1550, 1587, 1702

bp_rci defined in line 181; used 12 times

- in line 715-717(2), 1127, 1135, 1241-1245(2), 1254, 1493, 1627, 1721, 1829-1834(2)

bp_rct1 defined in line 183; used 22 times

- in line 758, 774, 799, 1184, 1376, 1388, 1406, 1437, 1456, 1507-1511(3), 1522-1524(2), 1675-1682(3), 2048, 2056-2058(2), 2065, 2075

bp_rct2 defined in line 184; used 5 times

- in line 1516-1520(2), 1529, 1678, 1685

bp_tmp defined in line 186; used 5 times

- in line 621, 629, 635, 1274, 1298

bp_tp defined in line 185; used 4 times

- in line 1297-1305(4)

buf defined in line 105; used 22 times

- in line 181-186(6), 579, 685-689(2), 890, 918, 992, 1283, 1297-1302(4), 1564, 1772, 2123, 2173-2175(2)

cmd defined in line 262; used 11 times

- in line 351-352(2), 361-362(2), 377-379(2), 391, 1604, 1641, 1733, 1844

cn defined in line 258; used 69 times

- in line 401-403(3), 445-457(6), 564, 574, 672, 682, 699, 707, 782, 832, 925-929(2), 993, 1012, 1050, 1164-1165(2), 1212, 1284-1290(4), 1331, 1339-1341(2), 1368-1369(2), 1551, 1565, 1588-1591(3), 1600(2), 1763-1764(2), 1772-1773(2), 1827-1831(2), 1905, 1936-1938(3), 1946, 1974-1976(3), 1986-1989(3), 1997-2000(3), 2040-2042(4), 2126-2135(4)

dip defined in line 248; used 21 times

- in line 552-554(2), 576, 594, 627, 642, 658-660(2), 863, 882, 923, 1008, 1827, 1883-1886(5), 1901-1903(2), 2133

dkinfo defined in line 89; used 4 times

- in line 1859, 1878-1883(3)

dn defined in line 264; used 6 times

- in line 1895-1901(6)

dt defined in line 263; used 3 times

- in line 1882-1887(3)

fd defined in line 252; used 64 times

- in line 398-399(2), 546, 558, 577-579(2), 619-629(4), 635, 664, 684-689(4), 695, 821, 888-890(2), 897, 916-918(2), 990-992(2), 1204-1207(2), 1280-1283(2), 1304-1305(2), 1325-1330(2), 1545-1550(2), 1562-1564(2), 1582-1587(2), 1647-1648(2), 1698-1702(2), 1739-1740(2), 1749-1750(2), 1760-1763(2), 1769-1772(2), 1819, 1943-1945(2), 1982-1985(2), 1993-1996(2), 2121-2123(2), 2171-2175(4)

feb_nc1 defined in line 326; used 5 times

- in line 933, 955, 999, 1024, 1052

feb_nc2 defined in line 328; used 5 times

- in line 934, 956, 1000, 1025, 1053

fewarn defined in line 300; used 4 times

- in line 614-615(2), 869-870(2)

first_level defined in line 268; used 3 times

- in line 1393, 1415, 1421

firstblk defined in line 265; used 4 times

- in line 1366, 1426, 1443, 1465

fn defined in line 261; used 6 times

- in line 559, 665, 696, 1819-1821(2), 1901

force defined in line 256; used 4 times

- in line 357, 644, 1333, 1342

help defined in line 272; used 2 times

- in line 366-367(2)

line defined in line 260; used 21 times

- in line 570-573(3), 651-652(2), 678-681(3), 711-712(2), 737-738(2), 834-838(3), 849-853(3), 1909-1913(3)

nb defined in line 249; used 9 times

- in line 882-887(6), 893-894(2), 915

nbc defined in line 249; used 6 times

- in line 880-886(3), 894-898(3)

nblk defined in line 249; used 9 times

- in line 851-860(6), 885-886(2), 895

ndemsg defined in line 330; used 3 times

- in line 979, 1046, 1060

nondataerr defined in line 269; used 5 times

- in line 1272, 1294-1296(2), 1654-1656(2)

off_bottom defined in line 266; used 3 times

- in line 1394, 1411-1414(2)

off_top defined in line 267; used 4 times

- in line 1394, 1413-1414(3)

pwstr defined in line 325; used 1 times

- in line 652

rb_bad defined in line 334; used 2 times

- in line 973, 1039

rb_uecc defined in line 332; used 2 times

- in line 969, 1034

rbn defined in line 249; used 19 times

- in line 915-916(4), 922-927(2), 936, 949-954(2), 960-965(2), 985-990(2), 998-1003(2), 1014, 1023, 1029, 1055

rcnt defined in line 252; used 4 times

- in line 890-891(2), 918-919(2)

rctcopy defined in line 338; used 7 times

- in line 359, 712-714(4), 1940(2)

repcnt defined in line 251; used 12 times

- in line 878, 900-902(2), 908, 947, 957-964(3), 1016-1030(4)

rp_blk defined in line 157; used 29 times

- in line 1169-1171(2), 1184-1185(2), 1372-1377(3), 1386, 1405, 1423-1425(2), 1433-1443(4), 1454-1464(3), 1470, 1515, 1524-1530(5), 1677-1684(4)

rp_bps defined in line 149; used 20 times

- in line 1082, 1097, 1109, 1192, 1220, 1234, 1261, 1314, 1349, 1473, 1500, 1537, 1615, 1634, 1665, 1690, 1709, 1726, 1911-1913(2)

rp_delta defined in line 161; used 6 times

- in line 1395-1397(2), 1417-1419(4)

rp_didit defined in line 154; used 4 times

- in line 1091, 1611, 1642, 1651

rp_dirty defined in line 173; used 16 times

- in line 562, 668, 828, 1116, 1126, 1151, 1556, 1649-1650(2), 1736-1737(2), 1826, 1836-1843(4)

rp_hblk defined in line 155; used 6 times

- in line 1167-1171(2), 1179, 1370-1372(2), 1443

rp_hoff defined in line 156; used 7 times

- in line 1168-1171(2), 1179, 1371-1373(2), 1397, 1427

rp_irs defined in line 163; used 13 times

- in line 1137-1139(2), 1200, 1208, 1214, 1251, 1304, 1328-1332(2), 1340, 1585, 1591, 1700

rp_l defined in line 171; used 6 times

- in line 1164-1168(3), 1368-1371(3)

rp_lbn defined in line 152; used 24 times

- in line 645, 927, 1149-1150(2), 1167-1168(2), 1176, 1204, 1246, 1280, 1325, 1361, 1370-1371(2), 1507, 1545, 1562, 1568, 1582, 1698, 1738, 1760, 1769, 2058

rp_oblk defined in line 159; used 11 times

- in line 1177-1179(2), 1512-1517(4), 1528, 1677, 1684-1686(3)

rp_off defined in line 158; used 28 times

- in line 1170-1171(2), 1373, 1386-1388(2), 1397-1398(3), 1405-1412(4), 1427, 1434, 1441, 1454-1456(2), 1462-1463(2), 1470, 1507-1511(3), 1675, 2048, 2056-2058(2), 2065

rp_ooff defined in line 160; used 7 times

- in line 1178-1179(2), 1513, 1520-1522(2), 1678-1680(2)

rp_orbd defined in line 168; used 8 times

- in line 1176-1182(3), 1388, 1406, 1456, 1678-1680(2)

rp_orbn defined in line 167; used 9 times

- in line 1162, 1177-1178(2), 1386, 1405, 1454, 1485, 1512-1513(2)

rp_prev defined in line 166; used 12 times

- in line 1093, 1161, 1175, 1367, 1385, 1404, 1453, 1484, 1514, 1528, 1676, 1684

rp_pri defined in line 169; used 6 times

- in line 1093, 1172, 1367, 1381, 1508, 1547

rp_r defined in line 172; used 6 times

- in line 1165-1168(3), 1369-1371(3)

rp_rbn defined in line 153; used 6 times

- in line 1156, 1169-1170(2), 1470, 1480, 1549

rp_sec defined in line 170; used 5 times

- in line 1093, 1174, 1367, 1400, 1449

rp_wcs7 defined in line 164; used 9 times

- in line 1273, 1286-1296(4), 1304-1306(3), 1333

rp_wcs8 defined in line 165; used 1 times

- in line 1324

rsize defined in line 251; used 3 times

- in line 887-891(3)

rwfem defined in line 255; used 8 times

- in line 867-868(2), 874, 932, 953, 997, 1022, 1051

sbn defined in line 249; used 9 times

- in line 836-839(4), 848-851(2), 858-859(2), 879

unit defined in line 259; used 29 times

- in line 402-403(2), 445-457(6), 564, 574, 672, 682, 699, 707, 832, 1164-1165(2), 1368-1369(2), 1827-1831(2), 1900, 1936-1938(3), 1974-1976(3), 2040

us defined in line 249; used 8 times

- in line 832, 839, 848-851(2), 858-859(2), 883-884(2)

ynline defined in line 2093; used 7 times

- in line 2098-2104(7)

#### Defined struct's

dkinfo defined in line 82; used 4 times

- in line 248(2), 1854(2)

rct_rci defined in line 193; used 11 times

- in line 181, 342(2), 1135(2), 1245(2), 1817(2), 1834(2)

#### Defined union's

rctb defined in line 219; used 10 times

- in line 183-184(2), 1931(2), 1968(2), 2019-2021(4)

#### Defined macros

BB_COOP defined in line 78; used 6 times

- in line 90-92(3), 101, 642, 1827

BB_NONE defined in line 80; used 5 times

- in line 93-94(2), 552, 658, 863

BB_RWRT defined in line 79; used 10 times

- in line 95-100(6), 576, 594, 627, 2133

BR_BBR defined in line 137; used 2 times

- in line 583, 2129

BR_CECC defined in line 138; used 1 times

- in line 2148

BR_DEB defined in line 142; used 1 times

- in line 2134

BR_FEM defined in line 141; used 2 times

- in line 952, 2137

BR_NBBR defined in line 136; used 3 times

- in line 583, 950, 2131

BR_NDE defined in line 140; used 2 times

- in line 2152-2155(2)

BR_UECC defined in line 139; used 1 times

- in line 2150

EF_BBR defined in line 119; used 12 times

- in line 925, 1012, 1284, 1331, 1341, 1590(2), 1600, 1763, 1772, 2128-2133(2)

EF_BBU defined in line 120; used 1 times

- in line 1284

ERR defined in line 69; used 1 times

- in line 827

HELP defined in line 73; used 3 times

- in line 867-868(2), 2105

MD_CMP defined in line 112; used 4 times

- in line 1327, 1584, 1762, 1984

MD_ERR defined in line 113; used 5 times

- in line 1329, 1586, 1701, 1762, 1995

MD_HCE defined in line 126; used 1 times

- in line 1600

MD_PRI defined in line 116; used 1 times

- in line 1548

MD_SEC defined in line 114; used 3 times

- in line 1282, 1762, 1771

MD_SREC defined in line 115; used 3 times

- in line 1282, 1762, 1771

NO defined in line 72; used 24 times

- in line 617, 960, 1029, 1137, 1200, 1214, 1251, 1272, 1286-1290(2), 1306, 1328-1333(2), 1340, 1394, 1415, 1585, 1591, 1656, 1700, 1765, 1774, 2102, 2181

NOERR defined in line 70; used 4 times

- in line 397, 557, 663, 694

RCI_BR defined in line 131; used 3 times

- in line 730, 1160, 1489

RCI_FE defined in line 130; used 4 times

- in line 731, 1136, 1250-1252(2)

RCI_P1 defined in line 133; used 4 times

- in line 728, 1253, 1491, 1835

RCI_P2 defined in line 132; used 3 times

- in line 729, 1492, 1837

RCI_VP defined in line 129; used 3 times

- in line 732, 1623, 1717

RD defined in line 66; used 10 times

- in line 397, 694, 1128-1132(2), 1185, 1242, 1275, 1377, 1438, 1517

RP_AC defined in line 233; used 4 times

- in line 889, 1281, 1770, 2122

RP_RD defined in line 231; used 7 times

- in line 578, 626, 917, 991, 1205, 1563, 1944

RP_REP defined in line 232; used 1 times

- in line 1546

RP_WRT defined in line 230; used 9 times

- in line 620, 687, 1326, 1583, 1699, 1761, 1983, 1994, 2172

RW defined in line 68; used 3 times

- in line 557, 663, 827

ST_DAT defined in line 125; used 10 times

- in line 929, 993, 1050, 1212, 1565(2), 1591, 1989, 2000, 2132

ST_MSK defined in line 123; used 6 times

- in line 1551, 1588, 1989, 1997-2000(2), 2126

ST_SUC defined in line 124; used 6 times

- in line 1551, 1588, 1946, 1986, 1997, 2127

WRT defined in line 67; used 10 times

- in line 1228, 1255, 1494, 1525-1530(2), 1628, 1683-1686(2), 1722, 1798

YES defined in line 71; used 22 times

- in line 600, 874, 936, 1003, 1055, 1139, 1208, 1273, 1293-1296(3), 1304, 1324, 1332, 1393, 1411-1414(3), 1759, 1767, 2100, 2177

Last modified: 1989-01-06 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 4285 |