date and time created 88/12/16 11:12:32 by bostic
[unix-history] / usr / src / usr.sbin / bad144 / bad144.c
index a25d95d..7e9cd6d 100644 (file)
@@ -1,17 +1,28 @@
 /*
 /*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * Copyright (c) 1980,1986,1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
 #ifndef lint
 char copyright[] =
  */
 
 #ifndef lint
 char copyright[] =
-"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+"@(#) Copyright (c) 1980,1986,1988 Regents of the University of California.\n\
  All rights reserved.\n";
 #endif not lint
 
 #ifndef lint
  All rights reserved.\n";
 #endif not lint
 
 #ifndef lint
-static char sccsid[] = "@(#)bad144.c   5.4 (Berkeley) %G%";
+static char sccsid[] = "@(#)bad144.c   5.15 (Berkeley) %G%";
 #endif not lint
 
 /*
 #endif not lint
 
 /*
@@ -28,22 +39,29 @@ static char sccsid[] = "@(#)bad144.c        5.4 (Berkeley) %G%";
  * RP06 sectors are marked as bad by inverting the format bit in the
  * header; on other drives the valid-sector bit is cleared.
  */
  * RP06 sectors are marked as bad by inverting the format bit in the
  * header; on other drives the valid-sector bit is cleared.
  */
-#include <sys/types.h>
+#include <sys/param.h>
 #include <sys/dkbad.h>
 #include <sys/ioctl.h>
 #include <sys/dkbad.h>
 #include <sys/ioctl.h>
+#include <sys/fs.h>
 #include <sys/file.h>
 #include <sys/file.h>
-#include <machine/dkio.h>
 
 #include <stdio.h>
 
 #include <stdio.h>
-#include <disktab.h>
+#include <sys/disklabel.h>
 
 #define RETRIES        10              /* number of retries on reading old sectors */
 
 #define RETRIES        10              /* number of retries on reading old sectors */
+#define        RAWPART "c"             /* disk partition containing badsector tables */
 
 int    fflag, add, copy, verbose, nflag;
 int    compare();
 
 int    fflag, add, copy, verbose, nflag;
 int    compare();
-struct dkbad dkbad, oldbad;
+int    dups;
+int    badfile = -1;           /* copy of badsector table to use, -1 if any */
+#define MAXSECSIZE     1024
+struct dkbad curbad, oldbad;
+#define        DKBAD_MAGIC     0
+
+char   label[BBSIZE];
 daddr_t        size, getold(), badsn();
 daddr_t        size, getold(), badsn();
-struct disktab *dp;
+struct disklabel *dp;
 char   name[BUFSIZ];
 char   *malloc();
 off_t  lseek();
 char   name[BUFSIZ];
 char   *malloc();
 off_t  lseek();
@@ -61,9 +79,11 @@ main(argc, argv)
                (*argv)++;
                while (**argv) {
                        switch (**argv) {
                (*argv)++;
                while (**argv) {
                        switch (**argv) {
+#if vax
                            case 'f':
                                fflag++;
                                break;
                            case 'f':
                                fflag++;
                                break;
+#endif
                            case 'a':
                                add++;
                                break;
                            case 'a':
                                add++;
                                break;
@@ -77,58 +97,77 @@ main(argc, argv)
                                nflag++;
                                verbose++;
                                break;
                                nflag++;
                                verbose++;
                                break;
+                           default:
+                               if (**argv >= '0' && **argv <= '4') {
+                                       badfile = **argv - '0';
+                                       break;
+                               }
+                               goto usage;
                        }
                        (*argv)++;
                }
                argc--, argv++;
        }
                        }
                        (*argv)++;
                }
                argc--, argv++;
        }
-       if (argc < 2) {
+       if (argc < 1) {
+usage:
                fprintf(stderr,
                fprintf(stderr,
-                 "usage: bad144 [ -f ] type disk [ snum [ bn ... ] ]\n");
+                 "usage: bad144 [ -f ] disk [ snum [ bn ... ] ]\n");
                fprintf(stderr,
                fprintf(stderr,
-             "to read or overwrite bad-sector table, e.g.: bad144 rk07 hk0\n");
+             "to read or overwrite bad-sector table, e.g.: bad144 hp0\n");
                fprintf(stderr,
                fprintf(stderr,
-                 "or bad144 -a [ -f ] [ -c ] type disk  bn ...\n");
+                 "or bad144 -a [ -f ] [ -c ] disk  bn ...\n");
                fprintf(stderr, "where options are:\n");
                fprintf(stderr, "\t-a  add new bad sectors to the table\n");
                fprintf(stderr, "\t-f  reformat listed sectors as bad\n");
                fprintf(stderr, "\t-c  copy original sector to replacement\n");
                exit(1);
        }
                fprintf(stderr, "where options are:\n");
                fprintf(stderr, "\t-a  add new bad sectors to the table\n");
                fprintf(stderr, "\t-f  reformat listed sectors as bad\n");
                fprintf(stderr, "\t-c  copy original sector to replacement\n");
                exit(1);
        }
-       dp = getdiskbyname(argv[0]);
-       if (dp == NULL) {
-               fprintf(stderr, "%s: unknown disk type\n", argv[0]);
+       if (argv[0][0] != '/')
+               (void)sprintf(name, "/dev/r%s%s", argv[0], RAWPART);
+       else
+               strcpy(name, argv[0]);
+       f = open(name, argc == 1? O_RDONLY : O_RDWR);
+       if (f < 0)
+               Perror(name);
+       if (read(f, label, sizeof(label)) < 0) 
+               Perror("read");
+       for (dp = (struct disklabel *)(label + LABELOFFSET);
+           dp < (struct disklabel *)
+               (label + sizeof(label) - sizeof(struct disklabel));
+           dp = (struct disklabel *)((char *)dp + 64))
+               if (dp->d_magic == DISKMAGIC && dp->d_magic2 == DISKMAGIC)
+                       break;
+       if (dp->d_magic != DISKMAGIC || dp->d_magic2 != DISKMAGIC) {
+               fprintf(stderr, "Bad pack magic number (pack is unlabeled)\n");
                exit(1);
        }
                exit(1);
        }
-       if (argv[1][0] != '/')
-               (void)sprintf(name, "/dev/r%sc", argv[1]);
-       else
-               (void)strcpy(name, argv[1]);
-       argc -= 2;
-       argv += 2;
+       if (dp->d_secsize > MAXSECSIZE || dp->d_secsize <= 0) {
+               fprintf(stderr, "Disk sector size too large/small (%d)\n",
+                       dp->d_secsize);
+               exit(7);
+       }
        size = dp->d_nsectors * dp->d_ntracks * dp->d_ncylinders; 
        size = dp->d_nsectors * dp->d_ntracks * dp->d_ncylinders; 
+       argc--;
+       argv++;
        if (argc == 0) {
        if (argc == 0) {
-               f = open(name, O_RDONLY);
-               if (f < 0)
-                       Perror(name);
-               sn = getold(f, &dkbad);
+               sn = getold(f, &oldbad);
                printf("bad block information at sector %d in %s:\n",
                    sn, name);
                printf("bad block information at sector %d in %s:\n",
                    sn, name);
-               printf("cartridge serial number: %d(10)\n", dkbad.bt_csn);
-               switch (dkbad.bt_flag) {
+               printf("cartridge serial number: %d(10)\n", oldbad.bt_csn);
+               switch (oldbad.bt_flag) {
 
 
-               case -1:
+               case (u_short)-1:
                        printf("alignment cartridge\n");
                        break;
 
                        printf("alignment cartridge\n");
                        break;
 
-               case 0:
+               case DKBAD_MAGIC:
                        break;
 
                default:
                        break;
 
                default:
-                       printf("bt_flag=%x(16)?\n", dkbad.bt_flag);
+                       printf("bt_flag=%x(16)?\n", oldbad.bt_flag);
                        break;
                }
                        break;
                }
-               bt = dkbad.bt_bad;
+               bt = oldbad.bt_bad;
                for (i = 0; i < 126; i++) {
                        bad = (bt->bt_cyl<<16) + bt->bt_trksec;
                        if (bad < 0)
                for (i = 0; i < 126; i++) {
                        bad = (bt->bt_cyl<<16) + bt->bt_trksec;
                        if (bad < 0)
@@ -137,12 +176,9 @@ main(argc, argv)
                            bt->bt_cyl, bt->bt_trksec>>8, bt->bt_trksec&0xff);
                        bt++;
                }
                            bt->bt_cyl, bt->bt_trksec>>8, bt->bt_trksec&0xff);
                        bt++;
                }
-               (void) checkold();
+               (void) checkold(&oldbad);
                exit(0);
        }
                exit(0);
        }
-       f = open(name, (fflag || add)? O_RDWR: O_WRONLY);
-       if (f < 0)
-               Perror(name);
        if (add) {
                /*
                 * Read in the old badsector table.
        if (add) {
                /*
                 * Read in the old badsector table.
@@ -150,20 +186,21 @@ main(argc, argv)
                 * are in order.  Copy the old table to the new one.
                 */
                (void) getold(f, &oldbad);
                 * are in order.  Copy the old table to the new one.
                 */
                (void) getold(f, &oldbad);
-               i = checkold();
+               i = checkold(&oldbad);
                if (verbose)
                if (verbose)
-                       printf("Had %d bad sectors\n", i);
+                       printf("Had %d bad sectors, adding %d\n", i, argc);
                if (i + argc > 126) {
                        printf("bad144: not enough room for %d more sectors\n",
                                argc);
                        printf("limited to 126 by information format\n");
                        exit(1);
                }
                if (i + argc > 126) {
                        printf("bad144: not enough room for %d more sectors\n",
                                argc);
                        printf("limited to 126 by information format\n");
                        exit(1);
                }
-               dkbad = oldbad;
+               curbad = oldbad;
        } else {
        } else {
-               dkbad.bt_csn = atoi(*argv++);
+               curbad.bt_csn = atoi(*argv++);
                argc--;
                argc--;
-               dkbad.bt_mbz = 0;
+               curbad.bt_mbz = 0;
+               curbad.bt_flag = DKBAD_MAGIC;
                if (argc > 126) {
                        printf("bad144: too many bad sectors specified\n");
                        printf("limited to 126 by information format\n");
                if (argc > 126) {
                        printf("bad144: too many bad sectors specified\n");
                        printf("limited to 126 by information format\n");
@@ -177,15 +214,15 @@ main(argc, argv)
                daddr_t sn = atoi(*argv++);
                argc--;
                if (sn < 0 || sn >= size) {
                daddr_t sn = atoi(*argv++);
                argc--;
                if (sn < 0 || sn >= size) {
-                       printf("%d: out of range [0,%d) for %s\n",
-                           sn, size, dp->d_name);
+                       printf("%d: out of range [0,%d) for disk %s\n",
+                           sn, size, dp->d_typename);
                        errs++;
                        continue;
                }
                bn[i] = sn;
                        errs++;
                        continue;
                }
                bn[i] = sn;
-               dkbad.bt_bad[i].bt_cyl = sn / (dp->d_nsectors*dp->d_ntracks);
+               curbad.bt_bad[i].bt_cyl = sn / (dp->d_nsectors*dp->d_ntracks);
                sn %= (dp->d_nsectors*dp->d_ntracks);
                sn %= (dp->d_nsectors*dp->d_ntracks);
-               dkbad.bt_bad[i].bt_trksec =
+               curbad.bt_bad[i].bt_trksec =
                    ((sn/dp->d_nsectors) << 8) + (sn%dp->d_nsectors);
                i++;
        }
                    ((sn/dp->d_nsectors) << 8) + (sn%dp->d_nsectors);
                i++;
        }
@@ -193,8 +230,8 @@ main(argc, argv)
                exit(1);
        nbad = i;
        while (i < 126) {
                exit(1);
        nbad = i;
        while (i < 126) {
-               dkbad.bt_bad[i].bt_trksec = -1;
-               dkbad.bt_bad[i].bt_cyl = -1;
+               curbad.bt_bad[i].bt_trksec = -1;
+               curbad.bt_bad[i].bt_cyl = -1;
                i++;
        }
        if (add) {
                i++;
        }
        if (add) {
@@ -203,28 +240,46 @@ main(argc, argv)
                 * Then shuffle the replacement sectors so that
                 * the previous bad sectors get the same replacement data.
                 */
                 * Then shuffle the replacement sectors so that
                 * the previous bad sectors get the same replacement data.
                 */
-               qsort((char *)dkbad.bt_bad, nbad, sizeof (struct bt_bad),
+               qsort((char *)curbad.bt_bad, nbad, sizeof (struct bt_bad),
                    compare);
                    compare);
+               if (dups) {
+                       fprintf(stderr,
+"bad144: bad sectors have been duplicated; can't add existing sectors\n");
+                       exit(3);
+               }
                shift(f, nbad, nbad-new);
        }
                shift(f, nbad, nbad-new);
        }
-       for (i = 0; i < 10 && i < dp->d_nsectors; i += 2) {
+       if (badfile == -1)
+               i = 0;
+       else
+               i = badfile * 2;
+       for (; i < 10 && i < dp->d_nsectors; i += 2) {
                if (lseek(f, dp->d_secsize * (size - dp->d_nsectors + i),
                    L_SET) < 0)
                        Perror("lseek");
                if (verbose)
                        printf("write badsect file at %d\n",
                                size - dp->d_nsectors + i);
                if (lseek(f, dp->d_secsize * (size - dp->d_nsectors + i),
                    L_SET) < 0)
                        Perror("lseek");
                if (verbose)
                        printf("write badsect file at %d\n",
                                size - dp->d_nsectors + i);
-               if (nflag == 0 &&
-                   write(f, (caddr_t)&dkbad, sizeof dkbad) != sizeof dkbad) {
+               if (nflag == 0 && write(f, (caddr_t)&curbad, sizeof(curbad)) !=
+                   sizeof(curbad)) {
                        char msg[80];
                        (void)sprintf(msg, "bad144: write bad sector file %d",
                            i/2);
                        perror(msg);
                }
                        char msg[80];
                        (void)sprintf(msg, "bad144: write bad sector file %d",
                            i/2);
                        perror(msg);
                }
+               if (badfile != -1)
+                       break;
        }
        }
-       if (fflag)
+#ifdef vax
+       if (nflag == 0 && fflag)
                for (i = nbad - new; i < nbad; i++)
                        format(f, bn[i]);
                for (i = nbad - new; i < nbad; i++)
                        format(f, bn[i]);
+#endif
+#ifdef DIOCSBAD
+       if (nflag == 0 && ioctl(f, DIOCSBAD, (caddr_t)&curbad) < 0)
+               fprintf(stderr,
+       "Can't sync bad-sector file; reboot for changes to take effect\n");
+#endif
        exit(0);
 }
 
        exit(0);
 }
 
@@ -236,21 +291,25 @@ struct dkbad *bad;
        daddr_t sn;
        char msg[80];
 
        daddr_t sn;
        char msg[80];
 
-       for (i = 0; i < 10 && i < dp->d_nsectors; i += 2) {
+       if (badfile == -1)
+               i = 0;
+       else
+               i = badfile * 2;
+       for (; i < 10 && i < dp->d_nsectors; i += 2) {
                sn = size - dp->d_nsectors + i;
                if (lseek(f, sn * dp->d_secsize, L_SET) < 0)
                        Perror("lseek");
                sn = size - dp->d_nsectors + i;
                if (lseek(f, sn * dp->d_secsize, L_SET) < 0)
                        Perror("lseek");
-               if (read(f, (char *)bad, sizeof (*bad)) == sizeof (*bad)) {
+               if (read(f, (char *) bad, dp->d_secsize) == dp->d_secsize) {
                        if (i > 0)
                                printf("Using bad-sector file %d\n", i/2);
                        return(sn);
                }
                        if (i > 0)
                                printf("Using bad-sector file %d\n", i/2);
                        return(sn);
                }
-               (void)sprintf(msg, "bad144: read bad sector file at sn %d",
-                   sn);
+               (void)sprintf(msg, "bad144: read bad sector file at sn %d", sn);
                perror(msg);
                perror(msg);
+               if (badfile != -1)
+                       break;
        }
        }
-       fprintf(stderr,
-           "bad144: %s: can't read bad block info\n", name);
+       fprintf(stderr, "bad144: %s: can't read bad block info\n", name);
        exit(1);
        /*NOTREACHED*/
 }
        exit(1);
        /*NOTREACHED*/
 }
@@ -262,7 +321,7 @@ checkold()
        daddr_t sn, lsn;
        int errors = 0, warned = 0;
 
        daddr_t sn, lsn;
        int errors = 0, warned = 0;
 
-       if (oldbad.bt_flag != 0) {
+       if (oldbad.bt_flag != DKBAD_MAGIC) {
                fprintf(stderr, "bad144: %s: bad flag in bad-sector table\n",
                        name);
                errors++;
                fprintf(stderr, "bad144: %s: bad flag in bad-sector table\n",
                        name);
                errors++;
@@ -271,10 +330,9 @@ checkold()
                fprintf(stderr, "bad144: %s: bad magic number\n", name);
                errors++;
        }
                fprintf(stderr, "bad144: %s: bad magic number\n", name);
                errors++;
        }
-       lsn = 0;
        bt = oldbad.bt_bad;
        for (i = 0; i < 126; i++, bt++) {
        bt = oldbad.bt_bad;
        for (i = 0; i < 126; i++, bt++) {
-               if (bt->bt_cyl == -1 && bt->bt_trksec == -1)
+               if (bt->bt_cyl == 0xffff && bt->bt_trksec == 0xffff)
                        break;
                if ((bt->bt_cyl >= dp->d_ncylinders) ||
                    ((bt->bt_trksec >> 8) >= dp->d_ntracks) ||
                        break;
                if ((bt->bt_cyl >= dp->d_ncylinders) ||
                    ((bt->bt_trksec >> 8) >= dp->d_ntracks) ||
@@ -289,11 +347,18 @@ checkold()
                sn = (bt->bt_cyl * dp->d_ntracks +
                    (bt->bt_trksec >> 8)) *
                    dp->d_nsectors + (bt->bt_trksec & 0xff);
                sn = (bt->bt_cyl * dp->d_ntracks +
                    (bt->bt_trksec >> 8)) *
                    dp->d_nsectors + (bt->bt_trksec & 0xff);
-               if (sn < lsn && !warned) {
-                   fprintf(stderr, "bad144: bad sector file out of order\n");
+               if (i > 0 && sn < lsn && !warned) {
+                   fprintf(stderr,
+                       "bad144: bad sector file is out of order\n");
                    errors++;
                    warned++;
                }
                    errors++;
                    warned++;
                }
+               if (i > 0 && sn == lsn) {
+                   fprintf(stderr,
+                       "bad144: bad sector file contains duplicates (sn %d)\n",
+                       sn);
+                   errors++;
+               }
                lsn = sn;
        }
        if (errors)
                lsn = sn;
        }
        if (errors)
@@ -317,14 +382,14 @@ shift(f, new, old)
        new--; old--;
        while (new >= 0 && new != old) {
                if (old < 0 ||
        new--; old--;
        while (new >= 0 && new != old) {
                if (old < 0 ||
-                   compare(&dkbad.bt_bad[new], &oldbad.bt_bad[old]) > 0) {
+                   compare(&curbad.bt_bad[new], &oldbad.bt_bad[old]) > 0) {
                        /*
                         * Insert new replacement here-- copy original
                         * sector if requested and possible,
                         * otherwise write a zero block.
                         */
                        if (!copy ||
                        /*
                         * Insert new replacement here-- copy original
                         * sector if requested and possible,
                         * otherwise write a zero block.
                         */
                        if (!copy ||
-                           !blkcopy(f, badsn(&dkbad.bt_bad[new]), repl - new))
+                           !blkcopy(f, badsn(&curbad.bt_bad[new]), repl - new))
                                blkzero(f, repl - new);
                } else {
                        if (blkcopy(f, repl - old, repl - new) == 0)
                                blkzero(f, repl - new);
                } else {
                        if (blkcopy(f, repl - old, repl - new) == 0)
@@ -354,11 +419,12 @@ daddr_t s1, s2;
                        exit(20);
                }
        }
                        exit(20);
                }
        }
-       if (lseek(f, dp->d_secsize * s1, L_SET) < 0)
-               Perror("lseek");
-       for (tries = 0; tries < RETRIES; tries++)
+       for (tries = 0; tries < RETRIES; tries++) {
+               if (lseek(f, dp->d_secsize * s1, L_SET) < 0)
+                       Perror("lseek");
                if ((n = read(f, buf, dp->d_secsize)) == dp->d_secsize)
                        break;
                if ((n = read(f, buf, dp->d_secsize)) == dp->d_secsize)
                        break;
+       }
        if (n != dp->d_secsize) {
                fprintf(stderr, "bad144: can't read sector, %d: ", s1);
                if (n < 0)
        if (n != dp->d_secsize) {
                fprintf(stderr, "bad144: can't read sector, %d: ", s1);
                if (n < 0)
@@ -409,6 +475,8 @@ register struct bt_bad *b1, *b2;
                return(1);
        if (b1->bt_cyl < b2->bt_cyl)
                return(-1);
                return(1);
        if (b1->bt_cyl < b2->bt_cyl)
                return(-1);
+       if (b1->bt_trksec == b2->bt_trksec)
+               dups++;
        return (b1->bt_trksec - b2->bt_trksec);
 }
 
        return (b1->bt_trksec - b2->bt_trksec);
 }
 
@@ -420,6 +488,9 @@ register struct bt_bad *bt;
                + (bt->bt_trksec&0xff));
 }
 
                + (bt->bt_trksec&0xff));
 }
 
+#ifdef vax
+#include <machine/dkio.h>
+
 struct rp06hdr {
        short   h_cyl;
        short   h_trksec;
 struct rp06hdr {
        short   h_cyl;
        short   h_trksec;
@@ -462,7 +533,7 @@ struct      formats {
 /*ARGSUSED*/
 hpupformat(fp, dp, blk, buf, count)
        struct formats *fp;
 /*ARGSUSED*/
 hpupformat(fp, dp, blk, buf, count)
        struct formats *fp;
-       struct disktab *dp;
+       struct disklabel *dp;
        daddr_t blk;
        char *buf;
        int count;
        daddr_t blk;
        char *buf;
        int count;
@@ -483,7 +554,7 @@ hpupformat(fp, dp, blk, buf, count)
 /*ARGSUSED*/
 rp06format(fp, dp, blk, buf, count)
        struct formats *fp;
 /*ARGSUSED*/
 rp06format(fp, dp, blk, buf, count)
        struct formats *fp;
-       struct disktab *dp;
+       struct disklabel *dp;
        daddr_t blk;
        char *buf;
        int count;
        daddr_t blk;
        char *buf;
        int count;
@@ -504,14 +575,15 @@ format(fd, blk)
        register struct formats *fp;
        static char *buf;
        static char bufsize;
        register struct formats *fp;
        static char *buf;
        static char bufsize;
+       struct format_op fop;
        int n;
 
        for (fp = formats; fp->f_name; fp++)
        int n;
 
        for (fp = formats; fp->f_name; fp++)
-               if (strcmp(dp->d_name, fp->f_name) == 0)
+               if (strcmp(dp->d_typename, fp->f_name) == 0)
                        break;
        if (fp->f_name == 0) {
                fprintf(stderr, "bad144: don't know how to format %s disks\n",
                        break;
        if (fp->f_name == 0) {
                fprintf(stderr, "bad144: don't know how to format %s disks\n",
-                       dp->d_name);
+                       dp->d_typename);
                exit(2);
        }
        if (buf && bufsize < fp->f_bufsize) {
                exit(2);
        }
        if (buf && bufsize < fp->f_bufsize) {
@@ -532,34 +604,38 @@ format(fd, blk)
         * purpose format routine is specified, we allow it to
         * process the sector as well.
         */
         * purpose format routine is specified, we allow it to
         * process the sector as well.
         */
-       if (lseek(fd, (long)blk * dp->d_secsize, L_SET) < 0)
-               Perror("lseek");
        if (verbose)
                printf("format blk %d\n", blk);
        if (verbose)
                printf("format blk %d\n", blk);
-       if (ioctl(fd, DKIOCHDR, (char *)0) < 0)
-               Perror("ioctl");
-       if ((n = read(fd, buf, fp->f_bufsize)) < 0)
-               bzero(buf, fp->f_bufsize);
+       bzero((char *)&fop, sizeof(fop));
+       fop.df_buf = buf;
+       fop.df_count = fp->f_bufsize;
+       fop.df_startblk = blk;
+       bzero(buf, fp->f_bufsize);
+       if (ioctl(fd, DIOCRFORMAT, &fop) < 0)
+               perror("bad144: read format");
+       if (fp->f_routine &&
+           (*fp->f_routine)(fp, dp, blk, buf, fop.df_count) != 0)
+               return;
        if (fp->f_bic) {
                struct hpuphdr *xp = (struct hpuphdr *)buf;
 
                xp->hpup_cyl &= ~fp->f_bic;
        }
        if (fp->f_bic) {
                struct hpuphdr *xp = (struct hpuphdr *)buf;
 
                xp->hpup_cyl &= ~fp->f_bic;
        }
-       if (fp->f_routine)
-               if ((*fp->f_routine)(fp, dp, blk, buf, n) != 0)
-                       return;
-       if (lseek(fd, (long)blk * dp->d_secsize, L_SET) < 0)
-               Perror("lseek");
        if (nflag)
                return;
        if (nflag)
                return;
-       if (ioctl(fd, DKIOCHDR, (char *)0) < 0)
-               Perror("ioctl");
-       if (write(fd, buf, fp->f_bufsize) != fp->f_bufsize) {
+       bzero((char *)&fop, sizeof(fop));
+       fop.df_buf = buf;
+       fop.df_count = fp->f_bufsize;
+       fop.df_startblk = blk;
+       if (ioctl(fd, DIOCWFORMAT, &fop) < 0)
+               Perror("write format");
+       if (fop.df_count != fp->f_bufsize) {
                char msg[80];
                (void)sprintf(msg, "bad144: write format %d", blk);
                perror(msg);
        }
 }
                char msg[80];
                (void)sprintf(msg, "bad144: write format %d", blk);
                perror(msg);
        }
 }
+#endif
 
 Perror(op)
        char *op;
 
 Perror(op)
        char *op;