Annotation of 42BSD/etc/bad144.c, revision 1.1.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.