Annotation of 42BSD/etc/bad144.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char *sccsid = "@(#)bad144.c    4.7 (Berkeley) 83/07/27";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * bad144
        !             7:  *
        !             8:  * This program prints and/or initializes a bad block record for a pack,
        !             9:  * in the format used by the DEC standard 144.
        !            10:  *
        !            11:  * BUGS:
        !            12:  *     Only reads/writes the first of the bad block record (sector 0
        !            13:  *     of the last track of the disk); in fact, there are copies
        !            14:  *     of the information in the first 5 even numbered sectors of this
        !            15:  *     track, but UNIX uses only the first, and we don't bother with the
        !            16:  *     others.
        !            17:  *
        !            18:  * It is preferable to write the bad information with a standard formatter,
        !            19:  * but this program will do in a pinch, e.g. if the bad information is
        !            20:  * accidentally wiped out this is a much faster way of restoring it than
        !            21:  * reformatting. 
        !            22:  * 
        !            23:  * RP06 sectors are marked as bad by inverting the format bit in the
        !            24:  * header; on other drives the BSE bit is set.
        !            25:  */
        !            26: #include <sys/types.h>
        !            27: #include <sys/dkbad.h>
        !            28: #include <sys/ioctl.h>
        !            29: #include <sys/file.h>
        !            30: #include <machine/dkio.h>
        !            31: 
        !            32: #include <stdio.h>
        !            33: #include <disktab.h>
        !            34: 
        !            35: int    fflag;
        !            36: struct dkbad dkbad;
        !            37: 
        !            38: main(argc, argv)
        !            39:        int argc;
        !            40:        char *argv[];
        !            41: {
        !            42:        register struct bt_bad *bt;
        !            43:        register struct disktab *dp;
        !            44:        char name[BUFSIZ];
        !            45:        int size, i, f, bad, oldbad, errs;
        !            46: 
        !            47:        argc--, argv++;
        !            48:        if (argc > 0 && strcmp(*argv, "-f") == 0) {
        !            49:                argc--, argv++;
        !            50:                fflag++;
        !            51:        }
        !            52:        if (argc < 2) {
        !            53:                fprintf(stderr,
        !            54:                  "usage: bad144 [ -f ] type disk [ snum [ bn ... ] ]\n");
        !            55:                fprintf(stderr, "e.g.: bad144 rk07 hk0\n");
        !            56:                exit(1);
        !            57:        }
        !            58:        dp = getdiskbyname(argv[0]);
        !            59:        if (dp == NULL) {
        !            60:                fprintf(stderr, "%s: unknown disk type\n", argv[0]);
        !            61:                exit(1);
        !            62:        }
        !            63:        sprintf(name, "/dev/r%sc", argv[1]);
        !            64:        argc -= 2;
        !            65:        argv += 2;
        !            66:        size = dp->d_nsectors * dp->d_ntracks * dp->d_ncylinders; 
        !            67:        if (argc == 0) {
        !            68:                f = open(name, O_RDONLY);
        !            69:                if (f < 0)
        !            70:                        Perror(name);
        !            71:                if (lseek(f, dp->d_secsize*(size-dp->d_nsectors), L_SET) < 0)
        !            72:                        Perror("lseek");
        !            73:                printf("bad block information at sector %d in %s:\n",
        !            74:                    tell(f)/512, name);
        !            75:                if (read(f, &dkbad, sizeof (struct dkbad)) !=
        !            76:                    sizeof (struct dkbad)) {
        !            77:                        fprintf("bad144: %s: can't read bad block info\n");
        !            78:                        exit(1);
        !            79:                }
        !            80:                printf("cartidge serial number: %d(10)\n", dkbad.bt_csn);
        !            81:                switch (dkbad.bt_flag) {
        !            82: 
        !            83:                case -1:
        !            84:                        printf("alignment cartridge\n");
        !            85:                        break;
        !            86: 
        !            87:                case 0:
        !            88:                        break;
        !            89: 
        !            90:                default:
        !            91:                        printf("bt_flag=%x(16)?\n", dkbad.bt_flag);
        !            92:                        break;
        !            93:                }
        !            94:                oldbad = 0;
        !            95:                bt = dkbad.bt_bad;
        !            96:                for (i = 0; i < 128; i++) {
        !            97:                        bad = (bt->bt_cyl<<16) + bt->bt_trksec;
        !            98:                        if (bad < 0)
        !            99:                                break;
        !           100:                        printf("sn=%d, cn=%d, tn=%d, sn=%d\n",
        !           101:                            (bt->bt_cyl*dp->d_ntracks + (bt->bt_trksec>>8)) *
        !           102:                                dp->d_nsectors + (bt->bt_trksec&0xff),
        !           103:                            bt->bt_cyl, bt->bt_trksec>>8, bt->bt_trksec&0xff);
        !           104:                        bt++;
        !           105:                }
        !           106:                exit(0);
        !           107:        }
        !           108:        f = open(name, 1 + fflag);
        !           109:        if (f < 0)
        !           110:                Perror(name);
        !           111:        dkbad.bt_csn = atoi(*argv++);
        !           112:        argc--;
        !           113:        dkbad.bt_mbz = 0;
        !           114:        if (argc > 126) {
        !           115:                printf("bad144: too many bad sectors specified\n");
        !           116:                printf("limited to 126 by information format\n");
        !           117:                exit(1);
        !           118:        }
        !           119:        errs = 0;
        !           120:        i = 0;
        !           121:        while (argc > 0) {
        !           122:                int sn = atoi(*argv++);
        !           123: 
        !           124:                argc--;
        !           125:                if (sn < 0 || sn >= size) {
        !           126:                        printf("%d: out of range [0,%d) for %s\n",
        !           127:                            sn, size, dp->d_name);
        !           128:                        errs++;
        !           129:                }
        !           130:                dkbad.bt_bad[i].bt_cyl = sn / (dp->d_nsectors*dp->d_ntracks);
        !           131:                sn %= (dp->d_nsectors*dp->d_ntracks);
        !           132:                dkbad.bt_bad[i].bt_trksec =
        !           133:                    ((sn/dp->d_nsectors) << 8) + (sn%dp->d_nsectors);
        !           134:                i++;
        !           135:        }
        !           136:        while (i < 126) {
        !           137:                dkbad.bt_bad[i].bt_trksec = -1;
        !           138:                dkbad.bt_bad[i].bt_cyl = -1;
        !           139:                i++;
        !           140:        }
        !           141:        if (errs)
        !           142:                exit(1);
        !           143:        if (lseek(f, dp->d_secsize * (size - dp->d_nsectors), L_SET) < 0)
        !           144:                Perror("lseek");
        !           145:        if (write(f, (caddr_t)&dkbad, sizeof (dkbad)) != sizeof (dkbad))
        !           146:                Perror(name);
        !           147:        if (fflag)
        !           148:                for (i = 0, bt = dkbad.bt_bad; i < 126; i++, bt++) {
        !           149:                        daddr_t bn;
        !           150: 
        !           151:                        bad = (bt->bt_cyl<<16) + bt->bt_trksec;
        !           152:                        if (bad < 0)
        !           153:                                break;
        !           154:                        bn = (bt->bt_cyl * dp->d_ntracks +
        !           155:                            (bt->bt_trksec >> 8)) *
        !           156:                            dp->d_nsectors + (bt->bt_trksec & 0xff);
        !           157:                        format(f, dp, bn);
        !           158:                }
        !           159:        exit(0);
        !           160: }
        !           161: 
        !           162: struct rp06hdr {
        !           163:        short   h_cyl;
        !           164:        short   h_trksec;
        !           165:        short   h_key1;
        !           166:        short   h_key2;
        !           167:        char    h_data[512];
        !           168: #define        RP06_FMT        010000          /* 1 == 16 bit, 0 == 18 bit */
        !           169: };
        !           170: 
        !           171: /*
        !           172:  * Most massbus and unibus drives
        !           173:  * have headers of this form
        !           174:  */
        !           175: struct hpuphdr {
        !           176:        u_short hpup_cyl;
        !           177:        u_short hpup_trksec;
        !           178:        char    hpup_data[512];
        !           179: #define        HPUP_OKSECT     0xc000          /* this normally means sector is good */
        !           180: };
        !           181: 
        !           182: struct formats {
        !           183:        char    *f_name;                /* disk name */
        !           184:        int     f_bufsize;              /* size of sector + header */
        !           185:        int     f_bic;                  /* value to bic in hpup_cyl */
        !           186:        int     (*f_routine)();         /* routine for special handling */
        !           187: } formats[] = {
        !           188:        { "rp06",       sizeof (struct rp06hdr),        RP06_FMT,       0 },
        !           189:        { "eagle",      sizeof (struct hpuphdr),        HPUP_OKSECT,    0 },
        !           190:        { "capricorn",  sizeof (struct hpuphdr),        HPUP_OKSECT,    0 },
        !           191:        { 0, 0, 0, 0 }
        !           192: };
        !           193: 
        !           194: format(fd, dp, blk)
        !           195:        int fd;
        !           196:        struct disktab *dp;
        !           197:        daddr_t blk;
        !           198: {
        !           199:        register struct formats *fp;
        !           200:        char *buf, *malloc();
        !           201: 
        !           202:        for (fp = formats; fp->f_name; fp++)
        !           203:                if (strcmp(dp->d_name, fp->f_name) == 0)
        !           204:                        break;
        !           205:        if (fp->f_name == 0) {
        !           206:                fprintf(stderr, "bad144: don't know how to format %s disks\n",
        !           207:                        dp->d_name);
        !           208:                exit(2);
        !           209:        }
        !           210:        buf = malloc(fp->f_bufsize);
        !           211:        if (buf == NULL) {
        !           212:                fprintf(stderr, "bad144: can't allocate sector buffer\n");
        !           213:                exit(3);
        !           214:        }
        !           215:        /*
        !           216:         * Here we do the actual formatting.  All we really
        !           217:         * do is rewrite the sector header and flag the bad sector
        !           218:         * according to the format table description.  If a special
        !           219:         * purpose format routine is specified, we allow it to
        !           220:         * process the sector as well.
        !           221:         */
        !           222:        if (lseek(fd, (long)blk * 512, L_SET) < 0)
        !           223:                Perror("lseek");
        !           224:        if (ioctl(fd, DKIOCHDR, 0) < 0)
        !           225:                Perror("ioctl");
        !           226:        read(fd, buf, fp->f_bufsize);
        !           227:        if (fp->f_bic) {
        !           228:                struct hpuphdr *xp = (struct hpuphdr *)buf;
        !           229: 
        !           230:                xp->hpup_cyl &= ~fp->f_bic;
        !           231:        }
        !           232:        if (fp->f_routine)
        !           233:                (*fp->f_routine)(fp, dp, blk, buf);
        !           234:        if (lseek(fd, (long)blk * 512, L_SET) < 0)
        !           235:                Perror("lseek");
        !           236:        if (ioctl(fd, DKIOCHDR, 0) < 0)
        !           237:                Perror("ioctl");
        !           238:        if (write(fd, buf, fp->f_bufsize) != fp->f_bufsize)
        !           239:                Perror("write");
        !           240: }
        !           241: 
        !           242: Perror(op)
        !           243:        char *op;
        !           244: {
        !           245: 
        !           246:        fprintf(stderr, "bad144: "); perror(op);
        !           247:        exit(4);
        !           248: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.