reorganization to move ufsmount ops to be vnode ops;
[unix-history] / usr / src / sys / vax / stand / format.c
CommitLineData
da7c5cc6 1/*
0880b18e 2 * Copyright (c) 1980, 1986 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7#ifndef lint
8char copyright[] =
0880b18e 9"@(#) Copyright (c) 1980, 1986 Regents of the University of California.\n\
da7c5cc6 10 All rights reserved.\n";
61118353 11#endif /* not lint */
71da8ead 12
da7c5cc6 13#ifndef lint
b28b3a13 14static char sccsid[] = "@(#)format.c 7.6 (Berkeley) %G%";
61118353 15#endif /* not lint */
f5e63974 16
001cf9d7
SL
17/*
18 * Standalone program to do media checking
19 * and record bad block information on any
0f3feeae 20 * disk with the appropriate driver and RM03-style headers.
f5e63974
MK
21 * TODO:
22 * add new bad sectors to bad-sector table when formatting by track
23 * (rearranging replacements ala bad144 -a)
24 * multi-pass format for disks with skip-sector capability
001cf9d7 25 */
b28b3a13
KB
26#include "sys/param.h"
27#include "sys/dkbad.h"
28#include "sys/vmmac.h"
29#include "sys/disklabel.h"
61118353 30
b28b3a13
KB
31#include "../include/cpu.h"
32#include "../include/mtpr.h"
001cf9d7 33
b28b3a13 34#include "stand/saio.h"
001cf9d7
SL
35#include "savax.h"
36
37#define MAXBADDESC 126 /* size of bad block table */
38#define CHUNK 48 /* max # of sectors/io operation */
39#define SECTSIZ 512 /* standard sector size */
40#define HDRSIZ 4 /* number of bytes in sector header */
41
42#define SSERR 0
43#define BSERR 1
44
f834e141
MK
45#define SSDEV(fd) (ioctl((fd), SAIOSSDEV, (char *)0) == 0)
46#define MAXECCBITS 3
001cf9d7
SL
47
48struct sector {
49 u_short header1;
50 u_short header2;
51 char buf[SECTSIZ];
52};
53
54struct dkbad dkbad; /* bad sector table */
f834e141 55struct dkbad oldbad; /* old bad sector table */
001cf9d7
SL
56struct dkbad sstab; /* skip sector table */
57
58#define NERRORS 6
c68cea4f
SL
59static char *
60errornames[NERRORS] = {
0f3feeae 61#define FE_BSE 0
001cf9d7 62 "Bad sector",
0f3feeae
MK
63#define FE_WCE 1
64 "Write check",
001cf9d7 65#define FE_ECC 2
f834e141 66 "Hard ECC",
001cf9d7
SL
67#define FE_HARD 3
68 "Other hard",
69#define FE_TOTAL 4
f834e141 70 "Marked bad",
001cf9d7 71#define FE_SSE 5
f834e141 72 "Skipped",
001cf9d7
SL
73};
74
75int errors[NERRORS]; /* histogram of errors */
c68cea4f 76int pattern;
f834e141 77int maxeccbits;
001cf9d7 78
71da8ead
MK
79/*
80 * Purdue/EE severe burnin patterns.
81 */
82unsigned short ppat[] = {
fb9e17ff 830xf00f, 0xec6d, 0031463,0070707,0133333,0155555,0161616,0143434,
71da8ead
MK
840107070,0016161,0034343,0044444,0022222,0111111,0125252, 052525,
850125252,0125252,0125252,0125252,0125252,0125252,0125252,0125252,
86#ifndef SHORTPASS
870125252,0125252,0125252,0125252,0125252,0125252,0125252,0125252,
88 052525, 052525, 052525, 052525, 052525, 052525, 052525, 052525,
89#endif
90 052525, 052525, 052525, 052525, 052525, 052525, 052525, 052525
91 };
92
93#define NPT (sizeof (ppat) / sizeof (short))
fb9e17ff 94int maxpass, npat; /* subscript to ppat[] */
71da8ead 95int severe; /* nz if running "severe" burnin */
f834e141 96int ssdev; /* device supports skip sectors */
f5e63974 97int startcyl, endcyl, starttrack, endtrack;
f834e141
MK
98int nbads; /* subscript for bads */
99daddr_t bads[2*MAXBADDESC]; /* Bad blocks accumulated */
71da8ead 100
001cf9d7 101char *malloc();
71da8ead 102int qcompar();
001cf9d7 103char *prompt();
f5e63974 104daddr_t badsn();
001cf9d7
SL
105extern int end;
106
107main()
108{
61118353
KB
109 register struct sector *hdr;
110 register int sector, sn, i;
111 struct disklabel dl;
001cf9d7 112 struct sector *bp, *cbp;
61118353
KB
113 int lastsector, tracksize, rtracksize;
114 int unit, fd, resid, trk, cyl, debug, pass;
115 char *cp, *rbp, *rcbp;
001cf9d7
SL
116
117 printf("Disk format/check utility\n\n");
118
61118353
KB
119 /* enable the cache, as every little bit helps */
120 switch (cpu) {
121 case VAX_8600:
122 mtpr(CSWP, 3);
123 break;
124 case VAX_8200:
125 case VAX_750:
126 mtpr(CADR, 0);
127 break;
128 case VAX_780:
129 mtpr(SBIMT, 0x200000);
130 break;
131 }
132
001cf9d7 133again:
71da8ead
MK
134 nbads = 0;
135 cp = prompt("Enable debugging (0=none, 1=bse, 2=ecc, 3=bse+ecc)? ");
001cf9d7
SL
136 debug = atoi(cp);
137 if (debug < 0)
138 debug = 0;
139 for (i = 0; i < NERRORS; i++)
140 errors[i] = 0;
141 fd = getdevice();
61118353 142 ioctl(fd, SAIODEVDATA, &dl);
001cf9d7 143 printf("Device data: #cylinders=%d, #tracks=%d, #sectors=%d\n",
61118353 144 dl.d_ncylinders, dl.d_ntracks, dl.d_nsectors);
f834e141
MK
145 ssdev = SSDEV(fd);
146 if (ssdev) {
147 ioctl(fd, SAIOSSI, (char *)0); /* set skip sector inhibit */
61118353
KB
148 dl.d_nsectors++;
149 dl.d_secpercyl += dl.d_ntracks;
f834e141
MK
150 printf("(not counting skip-sector replacement)\n");
151 }
61118353 152 getrange(&dl);
c68cea4f 153 if (getpattern())
001cf9d7
SL
154 goto again;
155 printf("Start formatting...make sure the drive is online\n");
156 ioctl(fd, SAIONOBAD, (char *)0);
f834e141
MK
157 ioctl(fd, SAIORETRIES, (char *)0);
158 ioctl(fd, SAIOECCLIM, (char *)maxeccbits);
001cf9d7 159 ioctl(fd, SAIODEBUG, (char *)debug);
61118353
KB
160 tracksize = sizeof (struct sector) * dl.d_nsectors;
161 rtracksize = SECTSIZ * dl.d_nsectors;
001cf9d7 162 bp = (struct sector *)malloc(tracksize);
71da8ead 163 rbp = malloc(rtracksize);
fb9e17ff
MK
164 pass = 0;
165 npat = 0;
166more:
167 for (; pass < maxpass; pass++) {
71da8ead
MK
168 if (severe)
169 printf("Begin pass %d\n", pass);
170 bufinit(bp, tracksize);
171 if (severe)
172 npat++;
001cf9d7 173 /*
71da8ead 174 * Begin check, for each track,
001cf9d7 175 *
71da8ead
MK
176 * 1) Write header and test pattern.
177 * 2) Read data. Hardware checks header and data ECC.
fb9e17ff 178 * Read data (esp on Eagles) is much faster than write check.
001cf9d7 179 */
61118353
KB
180 sector = ((startcyl * dl.d_ntracks) + starttrack) *
181 dl.d_nsectors;
182 lastsector = ((endcyl * dl.d_ntracks) + endtrack) *
183 dl.d_nsectors + dl.d_nsectors;
184 for ( ; sector < lastsector; sector += dl.d_nsectors) {
185 cyl = sector / dl.d_secpercyl;
186 trk = ((sector % dl.d_secpercyl) / dl.d_nsectors) << 8;
187 for (i = 0, hdr = bp; i < dl.d_nsectors; i++, hdr++) {
188 hdr->header1 = cyl | HDR1_FMT22 | HDR1_OKSCT;
189 hdr->header2 = trk + i;
71da8ead 190 }
61118353 191 if (sector && (sector % (dl.d_secpercyl * 50)) == 0)
71da8ead 192 printf("cylinder %d\n", cyl);
001cf9d7 193 /*
71da8ead
MK
194 * Try and write the headers and data patterns into
195 * each sector in the track. Continue until such
196 * we're done, or until there's less than a sector's
197 * worth of data to transfer.
198 *
199 * The lseek call is necessary because of
200 * the odd sector size (516 bytes)
001cf9d7 201 */
71da8ead 202 for (resid = tracksize, cbp = bp, sn = sector;;) {
61118353 203 register int cc;
71da8ead 204
305b4936 205 lseek(fd, sn * SECTSIZ, L_SET);
71da8ead
MK
206 ioctl(fd, SAIOHDR, (char *)0);
207 cc = write(fd, cbp, resid);
208 if (cc == resid)
209 break;
210 /*
211 * Don't record errors during write,
212 * all errors will be found during
f834e141 213 * check performed below.
71da8ead
MK
214 */
215 sn = iob[fd - 3].i_errblk;
216 cbp += sn - sector;
217 resid -= (sn - sector) * sizeof (struct sector);
218 if (resid < sizeof (struct sector))
219 break;
220 }
221 /*
222 * Read test patterns.
223 * Retry remainder of track on error until
224 * we're done, or until there's less than a
225 * sector to verify.
226 */
227 for (resid = rtracksize, rcbp = rbp, sn = sector;;) {
61118353 228 register int cc, rsn;
71da8ead 229
305b4936 230 lseek(fd, sn * SECTSIZ, L_SET);
71da8ead
MK
231 cc = read(fd, rcbp, resid);
232 if (cc == resid)
233 break;
234 sn = iob[fd-3].i_errblk;
f834e141 235 if (ssdev) {
61118353 236 rsn = sn - (sn / dl.d_nsectors);
f834e141
MK
237 printf("data ");
238 } else
239 rsn = sn;
240 printf("sector %d, read error\n\n", rsn);
61118353 241 if (recorderror(fd, sn, &dl) < 0 && pass > 0)
71da8ead
MK
242 goto out;
243 /* advance past bad sector */
244 sn++;
f834e141
MK
245 resid = rtracksize - ((sn - sector) * SECTSIZ);
246 rcbp = rbp + ((sn - sector) * SECTSIZ);
71da8ead
MK
247 if (resid < SECTSIZ)
248 break;
249 }
001cf9d7
SL
250 }
251 }
252 /*
253 * Checking finished.
254 */
71da8ead 255out:
fb9e17ff
MK
256 if (severe && maxpass < NPT) {
257 cp = prompt("More passes? (0 or number) ");
258 maxpass = atoi(cp);
259 if (maxpass > 0) {
260 maxpass += pass;
261 goto more;
262 }
263 }
71da8ead
MK
264 if (severe && nbads) {
265 /*
266 * Sort bads and insert in bad block table.
267 */
f834e141 268 qsort(bads, nbads, sizeof (daddr_t), qcompar);
71da8ead 269 severe = 0;
fb9e17ff
MK
270 errno = 0;
271 for (i = 0; i < nbads; i++)
61118353 272 recorderror(fd, bads[i], &dl);
71da8ead
MK
273 severe++;
274 }
001cf9d7 275 if (errors[FE_TOTAL] || errors[FE_SSE]) {
001cf9d7 276 /* change the headers of all the bad sectors */
61118353
KB
277 writebb(fd, errors[FE_SSE], &sstab, &dl, SSERR);
278 writebb(fd, errors[FE_TOTAL], &dkbad, &dl, BSERR);
001cf9d7 279 }
f834e141
MK
280 if (errors[FE_TOTAL] || errors[FE_SSE]) {
281 printf("Errors:\n");
282 for (i = 0; i < NERRORS; i++)
283 printf("%s: %d\n", errornames[i], errors[i]);
284 printf("Total of %d hard errors revectored\n",
285 errors[FE_TOTAL] + errors[FE_SSE]);
286 }
61118353
KB
287 if (endcyl == dl.d_ncylinders - 1 &&
288 (startcyl < dl.d_ncylinders - 1 || starttrack == 0)) {
f5e63974
MK
289 while (errors[FE_TOTAL] < MAXBADDESC) {
290 int i = errors[FE_TOTAL]++;
001cf9d7 291
f5e63974
MK
292 dkbad.bt_bad[i].bt_cyl = -1;
293 dkbad.bt_bad[i].bt_trksec = -1;
294 }
295 printf("\nWriting bad sector table at sector #%d\n",
61118353 296 dl.d_ncylinders * dl.d_secpercyl - dl.d_nsectors);
f5e63974 297 /* place on disk */
61118353
KB
298 for (i = 0; i < 10 && i < dl.d_nsectors; i += 2) {
299 lseek(fd, SECTSIZ * (dl.d_ncylinders *
300 dl.d_secpercyl - dl.d_nsectors + i), 0);
f5e63974
MK
301 write(fd, &dkbad, sizeof (dkbad));
302 }
303 } else if (errors[FE_TOTAL]) {
304 struct bt_bad *bt;
305
306 printf("New bad sectors (not added to table):\n");
307 bt = dkbad.bt_bad;
308 for (i = 0; i < errors[FE_TOTAL]; i++) {
61118353 309 printf("bn %d (cn=%d, tn=%d, sn=%d)\n", badsn(bt, &dl),
f5e63974
MK
310 bt->bt_cyl, bt->bt_trksec>>8, bt->bt_trksec&0xff);
311 bt++;
312 }
001cf9d7
SL
313 }
314 printf("Done\n");
315 ioctl(fd,SAIONOSSI,(char *)0);
316 close(fd);
317#ifndef JUSTEXIT
318 goto again;
319#endif
320}
321
71da8ead 322qcompar(l1, l2)
f834e141 323register daddr_t *l1, *l2;
71da8ead
MK
324{
325 if (*l1 < *l2)
326 return(-1);
327 if (*l1 == *l2)
328 return(0);
329 return(1);
330}
331
f5e63974 332daddr_t
61118353 333badsn(bt, lp)
f5e63974 334 register struct bt_bad *bt;
61118353 335 register struct disklabel *lp;
f5e63974 336{
61118353 337 register int ssoff = ssdev ? 1 : 0;
f834e141 338
61118353
KB
339 return ((bt->bt_cyl * lp->d_ntracks + (bt->bt_trksec >> 8)) *
340 (lp->d_nsectors - ssoff) + (bt->bt_trksec & 0xff) - ssoff);
f5e63974
MK
341}
342
001cf9d7 343/*
f5e63974 344 * Mark the bad/skipped sectors.
f834e141
MK
345 * Bad sectors on skip-sector devices are assumed to be skipped also,
346 * and must be done after the (earlier) first skipped sector.
001cf9d7 347 */
61118353 348writebb(fd, nsects, dbad, lp, sw)
001cf9d7
SL
349 int nsects, fd;
350 struct dkbad *dbad;
61118353 351 register struct disklabel *lp;
001cf9d7
SL
352{
353 struct sector bb_buf; /* buffer for one sector plus 4 byte header */
354 register int i;
355 int bn, j;
356 struct bt_bad *btp;
357
358 for (i = 0; i < nsects; i++) {
359 btp = &dbad->bt_bad[i];
360 if (sw == BSERR) {
361 bb_buf.header1 = HDR1_FMT22|btp->bt_cyl;
f834e141 362 if (ssdev)
001cf9d7
SL
363 bb_buf.header1 |= HDR1_SSF;
364 } else
365 bb_buf.header1 =
366 btp->bt_cyl | HDR1_FMT22 | HDR1_SSF | HDR1_OKSCT;
367 bb_buf.header2 = btp->bt_trksec;
61118353
KB
368 bn = lp->d_secpercyl * btp->bt_cyl +
369 lp->d_nsectors * (btp->bt_trksec >> 8) +
0f3feeae 370 (btp->bt_trksec & 0xff);
305b4936 371 lseek(fd, bn * SECTSIZ, L_SET);
001cf9d7
SL
372 ioctl(fd, SAIOHDR, (char *)0);
373 write(fd, &bb_buf, sizeof (bb_buf));
001cf9d7
SL
374 /*
375 * If skip sector, mark all remaining
376 * sectors on the track.
377 */
f834e141
MK
378 if (sw == SSERR) {
379 for (j = (btp->bt_trksec & 0xff) + 1, bn++;
61118353 380 j < lp->d_nsectors; j++, bn++) {
f834e141 381 bb_buf.header2 = j | (btp->bt_trksec & 0xff00);
305b4936 382 lseek(fd, bn * SECTSIZ, L_SET);
f834e141
MK
383 ioctl(fd, SAIOHDR, (char *)0);
384 write(fd, &bb_buf, sizeof (bb_buf));
385 }
001cf9d7
SL
386 }
387 }
388}
389
390/*
391 * Record an error, and if there's room, put
392 * it in the appropriate bad sector table.
71da8ead
MK
393 *
394 * If severe burnin store block in a list after making sure
395 * we have not already found it on a prev pass.
001cf9d7 396 */
61118353 397recorderror(fd, bn, lp)
001cf9d7 398 int fd, bn;
61118353 399 register struct disklabel *lp;
001cf9d7 400{
f5e63974 401 int cn, tn, sn;
61118353 402 register int i;
71da8ead 403
71da8ead
MK
404 if (severe) {
405 for (i = 0; i < nbads; i++)
406 if (bads[i] == bn)
407 return(0); /* bn already flagged */
f834e141 408 if (nbads >= (ssdev ? 2 * MAXBADDESC : MAXBADDESC)) {
f5e63974 409 printf("Bad sector table full, format terminating\n");
71da8ead
MK
410 return(-1);
411 }
412 bads[nbads++] = bn;
fb9e17ff
MK
413 if (errno < EBSE || errno > EHER)
414 return(0);
415 errno -= EBSE;
416 errors[errno]++;
71da8ead
MK
417 return(0);
418 }
fb9e17ff 419 if (errno >= EBSE && errno <= EHER) {
fb9e17ff
MK
420 errno -= EBSE;
421 errors[errno]++;
001cf9d7 422 }
61118353
KB
423 cn = bn / lp->d_secpercyl;
424 sn = bn % lp->d_secpercyl;
425 tn = sn / lp->d_nsectors;
426 sn %= lp->d_nsectors;
f834e141 427 if (ssdev) { /* if drive has skip sector capability */
f5e63974 428 int ss = errors[FE_SSE];
001cf9d7 429
f5e63974
MK
430 if (errors[FE_SSE] >= MAXBADDESC) {
431 /* this is bogus, we don't maintain skip sector table */
432 printf("Too many skip sector errors\n");
433 return(-1);
434 }
435 /* only one skip sector/track */
436 if (ss == 0 ||
437 tn != (sstab.bt_bad[ss - 1].bt_trksec >> 8) ||
438 cn != sstab.bt_bad[ss - 1].bt_cyl) {
f834e141
MK
439 /*
440 * Don't bother with skipping the extra sector
441 * at the end of the track.
442 */
61118353 443 if (sn == lp->d_nsectors - 1)
f834e141 444 return(0);
001cf9d7
SL
445 sstab.bt_bad[ss].bt_cyl = cn;
446 sstab.bt_bad[ss].bt_trksec = (tn<<8) + sn;
f5e63974
MK
447 errors[FE_SSE]++;
448 return(0);
001cf9d7 449 }
f5e63974
MK
450 }
451 if (errors[FE_TOTAL] >= MAXBADDESC) {
452 printf("Too many bad sectors\n");
453 return(-1);
001cf9d7
SL
454 }
455 /* record the bad sector address and continue */
0f3feeae 456 dkbad.bt_bad[errors[FE_TOTAL]].bt_cyl = cn;
001cf9d7 457 dkbad.bt_bad[errors[FE_TOTAL]++].bt_trksec = (tn << 8) + sn;
71da8ead 458 return(0);
001cf9d7
SL
459}
460
461/*
462 * Allocate memory on a page-aligned address.
463 * Round allocated chunk to a page multiple to
464 * ease next request.
465 */
466char *
467malloc(size)
468 int size;
469{
470 char *result;
471 static caddr_t last = 0;
472
473 if (last == 0)
474 last = (caddr_t)(((int)&end + 511) & ~0x1ff);
475 size = (size + 511) & ~0x1ff;
476 result = (char *)last;
477 last += size;
478 return (result);
479}
480
481/*
482 * Prompt and verify a device name from the user.
483 */
484getdevice()
485{
486 register char *cp;
001cf9d7
SL
487 int fd;
488
489top:
305b4936 490 do {
9259dd88
MK
491 printf(
492 "Enter device name as \"type(adaptor,controller,drive,0)\"\n");
305b4936
MK
493 cp = prompt("Device to format? ");
494 } while ((fd = open(cp, 2)) < 0);
9259dd88
MK
495 printf("Formatting %c%c drive %d on controller %d, adaptor %d: ",
496 cp[0], cp[1], iob[fd - 3].i_unit,
497 iob[fd - 3].i_ctlr, iob[fd - 3].i_adapt);
001cf9d7
SL
498 cp = prompt("verify (yes/no)? ");
499 while (*cp != 'y' && *cp != 'n')
500 cp = prompt("Huh, yes or no? ");
501 if (*cp == 'y')
502 return (fd);
503 goto top;
504}
505
f5e63974
MK
506/*
507 * Find range of tracks to format.
508 */
61118353
KB
509getrange(lp)
510 register struct disklabel *lp;
f5e63974 511{
61118353
KB
512 startcyl = getnum("Starting cylinder", 0, lp->d_ncylinders - 1, 0);
513 starttrack = getnum("Starting track", 0, lp->d_ntracks - 1, 0);
514 endcyl = getnum("Ending cylinder", 0, lp->d_ncylinders - 1,
515 lp->d_ncylinders - 1);
516 endtrack = getnum("Ending track", 0, lp->d_ntracks - 1,
517 lp->d_ntracks - 1);
f5e63974
MK
518}
519
520getnum(s, low, high, dflt)
61118353 521 int s, low, high, dflt;
f5e63974
MK
522{
523 char buf[132];
61118353 524 u_int val;
f5e63974 525
61118353 526 for(;;) {
f5e63974
MK
527 printf("%s (%d): ", s, dflt);
528 gets(buf);
529 if (buf[0] == 0)
530 return (dflt);
531 val = atoi(buf);
532 if (val >= low && val <= high)
533 return ((int)val);
534 printf("Value must be in range [%d,%d]\n", low, high);
535 }
536}
537
c68cea4f
SL
538static struct pattern {
539 long pa_value;
540 char *pa_name;
541} pat[] = {
542 { 0xf00ff00f, "RH750 worst case" },
543 { 0xec6dec6d, "media worst case" },
544 { 0xa5a5a5a5, "alternate 1's and 0's" },
fb9e17ff 545 { 0xFFFFFFFF, "Severe burnin (up to 48 passes)" },
c68cea4f
SL
546 { 0, 0 },
547};
548
549getpattern()
550{
551 register struct pattern *p;
552 int npatterns;
553 char *cp;
554
555 printf("Available test patterns are:\n");
556 for (p = pat; p->pa_value; p++)
557 printf("\t%d - (%x) %s\n", (p - pat) + 1,
558 p->pa_value & 0xffff, p->pa_name);
559 npatterns = p - pat;
560 cp = prompt("Pattern (one of the above, other to restart)? ");
561 pattern = atoi(cp) - 1;
fb9e17ff
MK
562 if (pattern < 0 || pattern >= npatterns)
563 return(1);
71da8ead 564 severe = 0;
fb9e17ff
MK
565 maxpass = 1;
566 if (pat[pattern].pa_value == -1) {
71da8ead 567 severe = 1;
fb9e17ff
MK
568 cp = prompt("How many passes (up to 48)? ");
569 maxpass = atoi(cp);
570 if (maxpass > NPT)
571 maxpass = NPT;
572 }
f834e141
MK
573 maxeccbits = getnum(
574 "Maximum number of bit errors to allow for soft ECC",
575 0, 11, MAXECCBITS);
fb9e17ff 576 return (0);
c68cea4f
SL
577}
578
579struct xsect {
580 u_short hd1;
581 u_short hd2;
582 long buf[128];
583};
584
585/*
586 * Initialize the buffer with the requested pattern.
587 */
588bufinit(bp, size)
589 register struct xsect *bp;
590 int size;
591{
592 register struct pattern *pptr;
593 register long *pp, *last;
594 register struct xsect *lastbuf;
71da8ead 595 int patt;
c68cea4f
SL
596
597 size /= sizeof (struct sector);
598 lastbuf = bp + size;
71da8ead
MK
599 if (severe) {
600 patt = ppat[npat] | ((long)ppat[npat] << 16);
601 printf("Write pattern 0x%x\n", patt&0xffff);
602 } else {
603 pptr = &pat[pattern];
604 patt = pptr->pa_value;
605 }
c68cea4f
SL
606 while (bp < lastbuf) {
607 last = &bp->buf[128];
608 for (pp = bp->buf; pp < last; pp++)
71da8ead 609 *pp = patt;
c68cea4f
SL
610 bp++;
611 }
612}
613
001cf9d7
SL
614char *
615prompt(msg)
616 char *msg;
617{
618 static char buf[132];
619
620 printf("%s", msg);
621 gets(buf);
622 return (buf);
623}