1 /* @(#)diskfmt.c 1.31 15/11/21 Copyright 1988-2015 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)diskfmt.c 1.31 15/11/21 Copyright 1988-2015 J. Schilling";
6 #endif
7 /*
8 * Format SCSI disks
9 *
10 * Copyright (c) 1988-2015 J. Schilling
11 */
12 /*
13 * The contents of this file are subject to the terms of the
14 * Common Development and Distribution License, Version 1.0 only
15 * (the "License"). You may not use this file except in compliance
16 * with the License.
17 *
18 * See the file CDDL.Schily.txt in this distribution for details.
19 * A copy of the CDDL is also available via the Internet at
20 * http://www.opensource.org/licenses/cddl1.txt
21 *
22 * When distributing Covered Code, include this CDDL HEADER in each
23 * file and include the License file CDDL.Schily.txt from this distribution.
24 */
25
26 #include <schily/stdio.h>
27 #include <schily/standard.h>
28 #include <schily/signal.h>
29 #include <schily/sigset.h>
30 #include <schily/stdlib.h>
31 #include <schily/unistd.h>
32 #include <schily/wait.h>
33 #include <schily/time.h>
34 #include <schily/string.h>
35 #include <schily/hostname.h>
36 #include <schily/schily.h>
37
38 #include "dsklabel.h"
39
40 #include <scg/scgcmd.h>
41 #include <scg/scsireg.h>
42 #include <scg/scsidefs.h>
43 #include <scg/scsitransp.h>
44
45 #include "scsicmds.h"
46
47 #include "defect.h"
48 #include "fmt.h"
49
50 #define strindex(s1, s2) strstr((s2), (s1))
51
52 extern struct timeval starttime;
53
54 extern char *Sbuf;
55 extern long Sbufsize;
56 extern int xdebug;
57 extern int debug;
58 extern int force;
59
60 extern int wrveri;
61 extern int n_test_patterns;
62 #define NWVERI n_test_patterns
63 extern int Nveri;
64 extern int Cveri;
65 extern int CWveri;
66 extern int noformat;
67 extern int save_mp;
68 extern int defmodes;
69 extern int no_heuristic_defaults;
70
71 struct scsi_format_data fmt;
72
73 extern int Prpart;
74 extern int label;
75 extern int autoformat;
76 extern int disable_mdl;
77 extern int setmodes;
78 extern int format_confirmed;
79 extern int format_done;
80
81 extern struct disk cur_disk;
82 extern struct disk alt_disk;
83
84 extern struct dk_label *d_label;
85
86 extern defect def;
87
88 EXPORT int printgeom __PR((SCSI *scgp, int current));
89 EXPORT void testformat __PR((SCSI *scgp, struct disk *dp));
90 LOCAL void print_diskgeom __PR((struct disk *dp));
91 EXPORT int Adaptec4000 __PR((SCSI *scgp));
92 LOCAL void get_Adaptec_defaults __PR((SCSI *scgp, struct disk *dp));
93 EXPORT int Emulex_MD21 __PR((SCSI *scgp));
94 EXPORT void get_defaults __PR((SCSI *scgp, struct disk *dp));
95 LOCAL void get_proto_defaults __PR((SCSI *scgp, struct disk *dp, struct disk *xp));
96 LOCAL void get_Emulex_defaults __PR((SCSI *scgp, struct disk *dp));
97 LOCAL void get_sony_defaults __PR((SCSI *scgp, struct disk *dp));
98 LOCAL void get_general_defaults __PR((struct disk *dp));
99 EXPORT void get_lgeom_defaults __PR((SCSI *scgp, struct disk *dp));
100 LOCAL void get_missing_defaults __PR((SCSI *scgp, struct disk *dp));
101 LOCAL BOOL confirmformat __PR((void));
102 LOCAL void sigalrm __PR((int sig));
103 LOCAL int prpercent __PR((long ftim));
104 LOCAL int format_disk __PR((SCSI *scgp, struct disk *dp, int clear_gdl));
105 EXPORT int reformat_disk __PR((SCSI *scgp, struct disk *dp));
106 EXPORT int acb_format_disk __PR((SCSI *scgp, struct disk *dp, int clear_gdl));
107 LOCAL void prconfig __PR((SCSI *scgp, struct disk *dp, struct disk *xp));
108
109 EXPORT int
printgeom(scgp,current)110 printgeom(scgp, current)
111 SCSI *scgp;
112 int current;
113 {
114 u_char mode[0x100];
115 u_char *p;
116 u_char *ep;
117
118 scgp->silent++;
119 getdev(scgp, FALSE);
120
121 /* XXX Quick and dirty, musz verallgemeinert werden !!! */
122
123 (void) unit_ready(scgp);
124 scgp->silent--;
125
126 fillbytes(mode, sizeof (mode), '\0');
127 if (mode_sense(scgp, mode, 0xFF, 0x3F, current?0:2) < 0) { /* All Pages */
128 if (mode_sense(scgp, mode, 0xFF, 0, 0) < 0) /* VU (block desc) */
129 return (-1);
130 }
131
132 if (scgp->verbose)
133 prbytes("Mode Sense Data", mode, 0xFF - scg_getresid(scgp));
134
135 ep = mode+mode[0]; /* Points to last byte of data */
136 p = &mode[4];
137 p += mode[3];
138 printf("Pages: ");
139 while (p < ep) {
140 printf("0x%x ", *p&0x3F);
141 p += p[1]+2;
142 }
143 printf("\n");
144
145 if (mode[3] == 8) {
146 printf("Density: 0x%x\n", mode[4]);
147 printf("Blocks: %ld\n", a_to_u_3_byte(&mode[5]));
148 printf("Blocklen:%ld\n", a_to_u_3_byte(&mode[9]));
149 }
150 p = &mode[4];
151 p += mode[3];
152 while (p < ep) {
153 if ((*p&0x3F) == 0x03) {
154 printf("Tr/zone: %d\n", a_to_u_2_byte(&p[2]));
155 printf("As/zone: %d\n", a_to_u_2_byte(&p[4]));
156 printf("At/zone: %d\n", a_to_u_2_byte(&p[6]));
157 printf("At/vol: %d\n", a_to_u_2_byte(&p[8]));
158 printf("Nsect: %d\n", a_to_u_2_byte(&p[10]));
159 printf("Psecsize:%d\n", a_to_u_2_byte(&p[12]));
160 printf("Tr skew: %d\n", a_to_u_2_byte(&p[16]));
161 printf("Cy skew: %d\n", a_to_u_2_byte(&p[18]));
162 }
163 if ((*p&0x3F) == 0x04) {
164 printf("Ncyl: %ld\n", a_to_u_3_byte(&p[2]));
165 printf("Nhead: %d\n", p[5]);
166 }
167 p += p[1]+2;
168 }
169 return (0);
170 }
171
172 EXPORT void
testformat(scgp,dp)173 testformat(scgp, dp)
174 SCSI *scgp;
175 struct disk *dp;
176 {
177 scgp->silent++;
178 if (read_capacity(scgp) >= 0) {
179 dp->formatted =
180 read_disk_label(scgp, (struct dk_label *)Sbuf, 0L);
181 /*
182 * XXX check if we might get problems.
183 */
184 if (dp->capacity != (scgp->cap->c_baddr + 1))
185 printf("WARNING: cap: %ld baddr+1: %ld\n",
186 dp->capacity, (long)scgp->cap->c_baddr + 1);
187
188 dp->capacity = dp->cur_capacity = scgp->cap->c_baddr + 1;
189 }
190 scgp->silent--;
191 printf("Disk %sformatted, %sLabel found.\n",
192 dp->formatted < 0 ? "un":"",
193 dp->formatted > 0 ? "":"no ");
194 if (dp->formatted > 0) {
195 printf("Current Label: '%s'\n",
196 getasciilabel((struct dk_label *)Sbuf));
197 }
198 if (autoformat)
199 dp->formatted = -1;
200 }
201
202 LOCAL void
print_diskgeom(dp)203 print_diskgeom(dp)
204 register struct disk *dp;
205 {
206 printf("Sektorsize : %ld Bytes\n", dp->secsize);
207 printf("Sektors/Track: %ld alt %ld\n", dp->spt,
208 dp->tpz <= 0 ? 0 : dp->aspz/dp->tpz);
209 printf("Cylinders: %ld alt %ld\n", dp->pcyl,
210 dp->nhead <= 0 ? 0 : dp->atrk/dp->nhead);
211 printf("Heads: %ld\n", dp->nhead);
212 }
213
214 EXPORT int
Adaptec4000(scgp)215 Adaptec4000(scgp)
216 SCSI *scgp;
217 {
218 struct disk *dp = &cur_disk;
219
220 testformat(scgp, dp); /* test if disk is formatted */
221
222 if (dp->formatted > 0) /* Sonst sind die Werte sinnlos */
223 get_acb4000defaults(scgp, dp);
224
225 get_ext_diskdata(scgp, scgp->inq->inq_vendor_info, dp);
226
227 if (!autoformat) { /* XXX */
228 read_primary_label(scgp, dp);
229 if (dp->labelread <= 0)
230 printf("No Label: Defaulting to Bull D585\n\n");
231 } else {
232 get_default_partition(scgp, dp);
233 }
234
235 if (!no_heuristic_defaults)
236 get_Adaptec_defaults(scgp, dp);
237
238 get_missing_defaults(scgp, dp);
239 get_general_defaults(dp);
240
241 if (dp->formatted > 0 && !yes("Ignore old defect List? "))
242 read_def_blk(scgp);
243 edit_def_blk();
244
245 print_diskgeom(dp);
246
247 if (!autoformat)
248 select_parameters(scgp, dp);
249
250 setlabel_from_val(scgp, dp, d_label);
251 if (Prpart) {
252 prconfig(scgp, dp, (struct disk *)0);
253 /* NOTREACHED */
254 }
255 if (label)
256 return (TRUE);
257
258 if (!yes("Set mode pages (needed for format)? "))
259 return (TRUE);
260
261 set_acb4000params(scgp, dp);
262 ext_modeselect(scgp, dp);
263
264 if (setmodes)
265 return (TRUE);
266
267 estimate_times(dp);
268 print_fmt_time(dp);
269
270 if (!confirmformat())
271 return (TRUE);
272
273 prdate();
274 getstarttime();
275
276 if (unit_ready(scgp))
277 return (acb_format_disk(scgp, dp, TRUE));
278 return (FALSE);
279 }
280
281
282 /*---------------------------------------------------------------------------
283 |
284 | Hier folgen default Werte fuer eine Bull D585 (Vertex V185)
285 |
286 +---------------------------------------------------------------------------*/
287
288 LOCAL void
get_Adaptec_defaults(scgp,dp)289 get_Adaptec_defaults(scgp, dp)
290 SCSI *scgp;
291 struct disk *dp;
292 {
293 if (dp->nhead < 0)
294 dp->nhead = 7;
295 if (dp->pcyl < 0)
296 dp->pcyl = 1166;
297 if (dp->tpz > 0)
298 comerrno(EX_BAD, "Bad tpz value.\n");
299 dp->tpz = 0;
300 if (dp->atrk > 0)
301 comerrno(EX_BAD, "Bad atrk value.\n");
302 dp->atrk = 0;
303 if (dp->lacyl < 0)
304 dp->lacyl = 3;
305 dp->int_cyl = 0;
306 if (dp->lncyl < 0)
307 dp->lncyl = dp->pcyl - dp->lacyl;
308 if (dp->spt < 0) {
309 if (scgp->dev == DEV_ACB4070)
310 dp->spt = 26;
311 else
312 dp->spt = 17;
313 }
314 if (dp->aspz > 0)
315 comerrno(EX_BAD, "Bad aspz value.\n");
316 dp->aspz = 0;
317 if (dp->rpm < 0)
318 dp->rpm = 3600;
319
320 if (dp->reduced_curr < 0)
321 dp->reduced_curr = dp->pcyl;
322 if (dp->write_precomp < 0)
323 dp->write_precomp = dp->pcyl;
324 if (dp->step_rate < 0)
325 dp->step_rate = 2;
326
327 if (dp->interleave < 0)
328 dp->interleave = 1;
329 if (dp->split_wv_cmd < 0)
330 dp->split_wv_cmd = 0;
331 if (dp->gap1 < 0)
332 dp->gap1 = 0;
333 if (dp->gap2 < 0)
334 dp->gap2 = 0;
335 get_lgeom_defaults(scgp, dp);
336 }
337
338 EXPORT int
Emulex_MD21(scgp)339 Emulex_MD21(scgp)
340 SCSI *scgp;
341 {
342 struct disk *dp = &cur_disk;
343 int cdl = TRUE;
344
345 if (debug)
346 printf("int_cyl: %ld lncyl: %ld\n", dp->int_cyl,
347 dp->lncyl);
348 testformat(scgp, dp); /* test if disk is formatted */
349
350 if (Prpart)
351 get_proto_defaults(scgp, dp, &alt_disk);
352 else
353 get_defaults(scgp, dp);
354 if (debug)
355 printf("int_cyl: %ld lncyl: %ld\n", dp->int_cyl,
356 dp->lncyl);
357
358 get_ext_diskdata(scgp, scgp->inq->inq_vendor_info, dp);
359 /*printf("XXX: disk_type: %s flags: %X\n", dp->disk_type, dp->flags);*/
360
361
362 if (debug)
363 printf("INQ_FOUND: %s (%lX)\n",
364 (dp->flags&(D_INQ_FOUND|D_FIRMW_FOUND))?"TRUE":"FALSE",
365 dp->flags);
366
367 if (!Prpart && !dp->disk_type && (dp->flags & D_INQ_FOUND)) {
368 int odefmodes = defmodes;
369
370 printf("WARNING: Inquiry for Controller found but no disk matches\n\n");
371 printf("This may be because current changeable media in not known\n");
372 printf("or because the disk has firmware bugs.\n\n");
373
374 printf("Trying to match disk with current mode pages:\n");
375 defmodes = FALSE;
376 alt_disk.formatted = 1;
377 get_defaults(scgp, &alt_disk);
378 alt_disk.formatted = dp->formatted;
379 defmodes = odefmodes;
380
381 get_ext_diskdata(scgp, scgp->inq->inq_vendor_info, &alt_disk);
382 alt_disk.capacity = dp->capacity;
383 alt_disk.cur_capacity = dp->cur_capacity;
384 if (alt_disk.disk_type)
385 movebytes(&alt_disk, dp, sizeof (struct disk));
386 else
387 printf("No match found.\n");
388 }
389 if (debug)
390 printf("int_cyl: %ld lncyl: %ld\n", dp->int_cyl,
391 dp->lncyl);
392
393 if (!autoformat) { /* XXX */
394 read_primary_label(scgp, dp);
395 if (dp->labelread <= 0)
396 printf("No Label: Defaulting to Drive values\n\n");
397 if (debug)
398 printf("int_cyl: %ld lncyl: %ld\n", dp->int_cyl,
399 dp->lncyl);
400 } else {
401 get_default_partition(scgp, dp);
402 }
403
404 if (!no_heuristic_defaults)
405 get_Emulex_defaults(scgp, dp);
406
407 get_missing_defaults(scgp, dp);
408 get_general_defaults(dp);
409
410 if (debug)
411 printf("int_cyl: %ld lncyl: %ld\n", dp->int_cyl,
412 dp->lncyl);
413
414 if (scgp->dev == DEV_SONY_SMO) {
415 if (dp->interleave == 1)
416 dp->interleave = 0;
417 }
418
419 print_diskgeom(dp);
420
421 if (!autoformat)
422 select_parameters(scgp, dp);
423
424 setlabel_from_val(scgp, dp, d_label);
425 if (debug && !Prpart)
426 prpartab(stdout, "", d_label);
427 if (Prpart) {
428 if (defmodes)
429 prconfig(scgp, dp, &alt_disk);
430 else
431 prconfig(scgp, &alt_disk, dp);
432 /* NOTREACHED */
433 }
434 if (label)
435 return (TRUE);
436
437 if (!autoformat) {
438 cdl = yes("Clear old grown defect list? ");
439 }
440
441 if (!yes("Set mode pages (needed for format)? "))
442 return (TRUE);
443
444 if (scgp->dev == DEV_SONY_SMO) {
445 if (dp->fmt_mode == 3)
446 save_mp = 0;
447 }
448 set_format_params(scgp, dp);
449 set_geom(scgp, dp);
450 set_error_rec_params(scgp, dp);
451 set_disre_params(scgp, dp);
452 if (scgp->dev == DEV_SONY_SMO)
453 set_sony_params(scgp, dp);
454 set_common_control(scgp, dp);
455 ext_modeselect(scgp, dp);
456
457 if (setmodes)
458 return (TRUE);
459
460 estimate_times(dp);
461 print_fmt_time(dp);
462
463 if (!confirmformat())
464 return (TRUE);
465
466 prdate();
467 getstarttime();
468
469 if (scgp->dev == DEV_SONY_SMO || unit_ready(scgp))
470 return (format_disk(scgp, dp, cdl));
471 return (FALSE);
472 }
473
474
475 EXPORT void
get_defaults(scgp,dp)476 get_defaults(scgp, dp)
477 SCSI *scgp;
478 struct disk *dp;
479 {
480 if (scgp->dev == DEV_SONY_SMO)
481 get_sony_defaults(scgp, dp);
482 else
483 get_mode_defaults(scgp, dp);
484 }
485
486 LOCAL void
get_proto_defaults(scgp,dp,xp)487 get_proto_defaults(scgp, dp, xp)
488 SCSI *scgp;
489 struct disk *dp; /* ptr to return main disk data */
490 struct disk *xp; /* ptr to return alt disk data */
491 {
492 int formatted = dp->formatted;
493 int odefmodes = defmodes;
494
495 /*
496 * If defmodes is TRUE,
497 * 'dp' points to default disk data and 'xp' points to current data
498 * else
499 * 'xp' points to default disk data and 'dp' points to current data
500 */
501 dp->formatted = 1; /* use only defmodes in modes.c */
502 get_defaults(scgp, dp);
503
504 defmodes = !defmodes;
505 dp->formatted = 1; /* use only defmodes in modes.c */
506 xp->formatted = 1; /* use only defmodes in modes.c */
507 get_defaults(scgp, xp);
508
509 dp->formatted = formatted;
510 xp->formatted = formatted;
511 defmodes = odefmodes;
512
513 get_lgeom_defaults(scgp, xp);
514 if (xp->lncyl < 0)
515 xp->lncyl = get_default_lncyl(scgp, xp);
516 get_missing_defaults(scgp, xp);
517 get_general_defaults(xp);
518 if (xp->cur_capacity < 0)
519 xp->cur_capacity = dp->cur_capacity;
520 }
521
522 /*---------------------------------------------------------------------------
523 |
524 | Hier folgen ungefaehre default Werte fuer eine CCS SCSI Platte
525 |
526 +---------------------------------------------------------------------------*/
527
528 LOCAL void
get_Emulex_defaults(scgp,dp)529 get_Emulex_defaults(scgp, dp)
530 SCSI *scgp;
531 struct disk *dp;
532 {
533 if (dp->tpz < 0)
534 dp->tpz = 1;
535 if (dp->atrk < 0 && dp->nhead > 0)
536 dp->atrk = 2 * dp->nhead;
537 if (strindex("EMULEX", scgp->inq->inq_vendor_info))
538 dp->int_cyl = 3;
539 else if (dp->int_cyl < 0)
540 dp->int_cyl = 0;
541 if (dp->aspz < 0)
542 dp->aspz = 1;
543 if (dp->rpm < 0)
544 dp->rpm = 3600;
545 if (dp->track_skew < 0)
546 dp->track_skew = 0;
547 if (dp->cyl_skew < 0)
548 dp->cyl_skew = 0;
549 if (dp->interleave < 0)
550 dp->interleave = 1; /* Interleaving Faktor */
551 if (dp->gap1 < 0)
552 dp->gap1 = 0;
553 if (dp->gap2 < 0)
554 dp->gap2 = 0;
555 get_lgeom_defaults(scgp, dp);
556 }
557
558
559 /*---------------------------------------------------------------------------
560 |
561 | Hier folgen default Werte fuer ein Sony SMO 501
562 |
563 +---------------------------------------------------------------------------*/
564
565 LOCAL void
get_sony_defaults(scgp,dp)566 get_sony_defaults(scgp, dp)
567 SCSI *scgp;
568 struct disk *dp;
569 {
570 scgp->silent++;
571 get_error_rec_defaults(scgp, dp);
572 get_disre_defaults(scgp, dp);
573 if (read_capacity(scgp) >= 0)
574 dp->secsize = scgp->cap->c_bsize;
575 get_sony_format_defaults(scgp, dp);
576 scgp->silent--;
577 if (no_heuristic_defaults)
578 return;
579 if (dp->nhead < 0)
580 dp->nhead = 1;
581 if (dp->pcyl < 0)
582 dp->pcyl = 18852;
583 if (dp->tpz < 0)
584 dp->tpz = 1;
585 dp->int_cyl = 174;
586 if (dp->spt < 0) {
587 if (dp->secsize == 512)
588 dp->spt = 31;
589 else if (dp->secsize == 1024)
590 dp->spt = 17;
591 }
592 if (dp->aspz < 0)
593 dp->aspz = 0;
594 if (dp->spare_band_size < 0)
595 dp->spare_band_size = 2048;
596 if (dp->atrk < 0) {
597 dp->atrk = dp->spare_band_size / dp->spt;
598 /* if (dp->spare_band_size % dp->spt)*/
599 /* ??? dp->atrk++;*/
600 }
601 if (dp->rpm < 0)
602 dp->rpm = 2400;
603 if (dp->track_skew < 0)
604 dp->track_skew = 0;
605 if (dp->cyl_skew < 0)
606 dp->cyl_skew = 0;
607 if (dp->interleave < 0)
608 dp->interleave = 0; /* Interleaving Faktor */
609 if (dp->fmt_pattern < 0)
610 dp->fmt_pattern = 3; /* MkCDA | MkPlst */
611 if (dp->fmt_mode < 0)
612 dp->fmt_mode = 3;
613 if (dp->def_lst_format < 0)
614 dp->def_lst_format = SC_DEF_PHYS;
615 if (dp->fmt_mode == 3)
616 save_mp = 0;
617 get_lgeom_defaults(scgp, dp);
618 if (dp->lncyl < 0 && dp->pcyl > 0) /*XXX hier ??*/
619 dp->lncyl = dp->pcyl
620 - dp->atrk/dp->nhead
621 - dp->lacyl - dp->int_cyl;
622 }
623
624 LOCAL void
get_general_defaults(dp)625 get_general_defaults(dp)
626 struct disk *dp;
627 {
628 if (dp->fmt_pattern < 0)
629 dp->fmt_pattern = 0;
630
631 if (dp->def_lst_format < 0)
632 dp->def_lst_format = SC_DEF_BLOCK;
633 if (dp->split_wv_cmd < 0)
634 dp->split_wv_cmd = 0;
635
636 if (!no_heuristic_defaults)
637 estimate_times(dp);
638
639 if (Cveri < 0)
640 Cveri = dp->veri_count > 0 ? dp->veri_count : CVERI;
641 if (CWveri < 0)
642 CWveri = dp->wr_veri_count > 0 ?
643 dp->wr_veri_count : CWVERI;
644 if (Nveri < 0) {
645 Nveri = dp->veri_loops > 0 ?
646 dp->veri_loops : (wrveri?NWVERI:NVERI);
647 if (wrveri)
648 Nveri *= 2;
649 }
650 }
651
652 EXPORT void
get_lgeom_defaults(scgp,dp)653 get_lgeom_defaults(scgp, dp)
654 SCSI *scgp;
655 struct disk *dp;
656 {
657 if (dp->lhead < 0)
658 dp->lhead = dp->nhead;
659 if (dp->lspt < 0)
660 dp->lspt = dp->spt;
661 if (dp->lacyl < 0)
662 dp->lacyl =
663 (old_acb(scgp->dev) || (dp->nhead == 1)) ? 2L : 1L;
664 if (dp->lpcyl < 0 ||
665 (dp->lpcyl != dp->pcyl && ((dp->flags & D_DISK_LPCYL) == 0))) {
666 /*
667 * Let us assume the sector size is 512 bytes.
668 * Sun Disk Labels allow (cheated) disks up to ~ 100 PB.
669 * The current SCSI standard only allows disks up to 1 TB.
670 * For this reason we make the conversion simple.
671 */
672 dp->lpcyl = dp->pcyl;
673 while (dp->lpcyl > 0xFFFE) {
674 dp->lhead *= 2;
675 dp->lpcyl /= 2;
676 }
677 dp->flags |= D_DISK_LPCYL;
678 }
679 }
680
681 LOCAL void
get_missing_defaults(scgp,dp)682 get_missing_defaults(scgp, dp)
683 SCSI *scgp;
684 struct disk *dp;
685 {
686 if (dp->rpm < 0) {
687 if (scgp->inq->data_format >= 2)
688 printf("Disk states to be SCSI-2 but really is not.\n");
689 printf("WARNING: disk rotation rate not known.\n");
690 if (!yes("Don't use 3600 as default? "))
691 dp->rpm = 3600;
692 }
693 if (!is_ccs(scgp->dev)) {
694 if (dp->track_skew < 0)
695 dp->track_skew = 0;
696 if (dp->cyl_skew < 0)
697 dp->cyl_skew = 0;
698 } else {
699 #ifdef needed
700 if (dp->reduced_curr < 0)
701 dp->reduced_curr = dp->pcyl;
702 if (dp->write_precomp < 0)
703 dp->write_precomp = dp->pcyl;
704 if (dp->step_rate < 0)
705 dp->step_rate = 0;
706 #endif
707 }
708 }
709
710 LOCAL BOOL
confirmformat()711 confirmformat()
712 {
713 if (noformat) {
714 printf("WARNING: The -noformat option has been specified.\n");
715 printf(" This inhibits formatting the disk regardles of the next confirmation.\n");
716 }
717 if (format_confirmed)
718 return (TRUE);
719
720 if (!yes("Format Disk destroys all Data. Really? ")) {
721 if (autoformat) {
722 printf("Platte wurde n i c h t formatiert.\n");
723 exit(EX_BAD);
724 }
725 return (FALSE);
726 }
727 format_confirmed = TRUE;
728 return (TRUE);
729 }
730
731 LOCAL void
sigalrm(sig)732 sigalrm(sig)
733 int sig;
734 {
735 }
736
737 LOCAL int
prpercent(ftim)738 prpercent(ftim)
739 long ftim;
740 {
741 #ifdef HAVE_FORK
742 int pid = fork();
743 int fatim;
744 struct timeval tv;
745
746 if (pid != 0)
747 return (pid);
748
749 fatim = ftim / 100;
750 if (fatim == 0)
751 fatim = 1;
752 for (;;) {
753 #ifdef SIGALRM
754 signal(SIGALRM, sigalrm);
755 alarm(fatim);
756 pause();
757 #endif
758 if (gettimeofday(&tv, (struct timezone *)0) < 0)
759 break;
760 printf("%4lld%%\b\b\b\b\b",
761 (Llong)(tv.tv_sec-starttime.tv_sec)*100/(Llong)ftim);
762 flush();
763 }
764 return (pid);
765 #else
766 return (999999999);
767 #endif
768 }
769
770 LOCAL int
format_disk(scgp,dp,clear_gdl)771 format_disk(scgp, dp, clear_gdl)
772 SCSI *scgp;
773 struct disk *dp;
774 int clear_gdl;
775 {
776 BOOL ret = FALSE;
777 sigset_t oldmask;
778 int pid;
779
780 if (!confirmformat())
781 return (TRUE);
782
783 format_done = FALSE;
784 if (noformat) {
785 printf("No Format!!\n");
786 return (TRUE);
787 }
788 read_sinfo(scgp, dp, TRUE);
789 printf("Formatting ... "); flush();
790 pid = prpercent(dp->fmt_time);
791
792 block_sigs(oldmask);
793 if (format_unit(scgp, &fmt, 0, (int)dp->def_lst_format,
794 disable_mdl, clear_gdl,
795 (int)dp->interleave,
796 (int)dp->fmt_pattern,
797 (int)dp->fmt_timeout) >= 0) {
798 format_done = TRUE;
799 if (rezero_unit(scgp) >= 0)
800 ret = TRUE;
801 } else if (force) {
802 if (yes("Continue? "))
803 ret = TRUE;
804 }
805 #ifdef SIGALRM
806 alarm(0);
807 #endif
808 printf("done.\n");
809 if (read_capacity(scgp) < 0)
810 ret = FALSE;
811 write_sinfo(scgp, dp);
812 label_disk(scgp, dp);
813 convert_def_blk(scgp);
814 write_def_blk(scgp, TRUE);
815 restore_sigs(oldmask);
816 #ifdef HAVE_FORK
817 #ifdef SIGKILL
818 kill(pid, SIGKILL);
819 #endif
820 while (wait(0) > 0)
821 ;
822 #endif
823 return (ret);
824 }
825
826 EXPORT int
reformat_disk(scgp,dp)827 reformat_disk(scgp, dp)
828 SCSI *scgp;
829 struct disk *dp;
830 {
831 BOOL ret = FALSE;
832 sigset_t oldmask;
833 int pid;
834
835 if (!confirmformat())
836 return (TRUE);
837
838 format_done = FALSE;
839 if (noformat) {
840 printf("No Reformat!!\n");
841 return (TRUE);
842 }
843 read_sinfo(scgp, dp, TRUE);
844 printf("Reformatting ... "); flush();
845 getstarttime();
846 pid = prpercent(dp->fmt_time);
847
848 block_sigs(oldmask);
849 if (format_unit(scgp, &fmt, 0, (int)dp->def_lst_format,
850 disable_mdl, FALSE,
851 (int)dp->interleave,
852 (int)dp->fmt_pattern,
853 (int)dp->fmt_timeout) >= 0) {
854 format_done = TRUE;
855 if (rezero_unit(scgp) >= 0)
856 ret = TRUE;
857 } else if (force) {
858 if (yes("Continue? "))
859 ret = TRUE;
860 }
861 #ifdef SIGALRM
862 alarm(0);
863 #endif
864 printf("done.\n");
865 if (read_capacity(scgp) < 0)
866 ret = FALSE;
867 write_sinfo(scgp, dp);
868 label_disk(scgp, dp);
869 convert_def_blk(scgp);
870 write_def_blk(scgp, TRUE);
871 restore_sigs(oldmask);
872 #ifdef HAVE_FORK
873 #ifdef SIGKILL
874 kill(pid, SIGKILL);
875 #endif
876 while (wait(0) > 0)
877 ;
878 #endif
879 return (ret);
880 }
881
882 #ifdef used
883 reformat_with_bad(dp)
884 struct disk *dp;
885 {
886 BOOL ret = FALSE;
887 sigset_t oldmask;
888 int pid;
889
890 if (!confirmformat())
891 return (TRUE);
892
893 format_done = FALSE;
894 if (noformat) {
895 printf("No Reformat!!\n");
896 return (TRUE);
897 }
898 read_sinfo(dp, TRUE);
899 printf("Reformatting ... "); flush();
900 getstarttime();
901 pid = prpercent(dp->fmt_time);
902
903 block_sigs(oldmask);
904 if (format_unit((struct scsi_format_data *)bad, nbad, SC_DEF_BLOCK,
905 disable_mdl, TRUE,
906 (int)dp->interleave,
907 (int)dp->fmt_pattern,
908 (int)dp->fmt_timeout) >= 0) {
909 format_done = TRUE;
910 if (rezero_unit() >= 0)
911 ret = TRUE;
912 } else if (force) {
913 if (yes("Continue? "))
914 ret = TRUE;
915 }
916 printf("done.\n");
917 if (read_capacity() < 0)
918 ret = FALSE;
919 write_sinfo(dp);
920 label_disk(dp);
921 convert_def_blk();
922 write_def_blk(TRUE);
923 restore_sigs(oldmask);
924 #ifdef HAVE_FORK
925 #ifdef SIGKILL
926 kill(pid, SIGKILL);
927 #endif
928 while (wait(0) > 0)
929 ;
930 #endif
931 return (ret);
932 }
933 #endif
934
935 EXPORT int
acb_format_disk(scgp,dp,clear_gdl)936 acb_format_disk(scgp, dp, clear_gdl)
937 SCSI *scgp;
938 struct disk *dp;
939 int clear_gdl;
940 {
941 BOOL ret = FALSE;
942 sigset_t oldmask;
943 int pid;
944
945 if (!confirmformat())
946 return (TRUE);
947
948 format_done = FALSE;
949 if (noformat) {
950 printf("No Format!!\n");
951 return (TRUE);
952 }
953 read_sinfo(scgp, dp, TRUE);
954 printf("Formatting ... "); flush();
955 pid = prpercent(dp->fmt_time);
956
957 block_sigs(oldmask);
958 if (format_unit(scgp, (struct scsi_format_data *)&def,
959 (int)a_to_u_2_byte(&def.d_size)/sizeof (def.d_def[0]),
960 SC_DEF_BFI, disable_mdl, clear_gdl,
961 (int)dp->interleave,
962 (int)dp->fmt_pattern,
963 (int)dp->fmt_timeout) >= 0) {
964 format_done = TRUE;
965 if (rezero_unit(scgp) >= 0)
966 ret = TRUE;
967 } else if (force) {
968 if (yes("Continue? "))
969 ret = TRUE;
970 }
971 #ifdef SIGALRM
972 alarm(0);
973 #endif
974 printf("done.\n");
975 if (read_capacity(scgp) < 0)
976 ret = FALSE;
977 write_sinfo(scgp, dp);
978 label_disk(scgp, dp);
979 convert_def_blk(scgp);
980 write_def_blk(scgp, TRUE);
981 restore_sigs(oldmask);
982 #ifdef HAVE_FORK
983 #ifdef SIGKILL
984 kill(pid, SIGKILL);
985 #endif
986 while (wait(0) > 0)
987 ;
988 #endif
989 return (ret);
990 }
991
992 LOCAL void
prconfig(scgp,dp,xp)993 prconfig(scgp, dp, xp)
994 SCSI *scgp;
995 struct disk *dp; /* ptr to default data */
996 struct disk *xp; /* ptr to current data */
997 {
998 FILE *f;
999 char name[80];
1000 char hname[257];
1001 char dname[257];
1002 BOOL fbug = FALSE;
1003 int cur_match = 0;
1004 int tot_match = 0;
1005
1006 if (dp && !dp->disk_type)
1007 dp->disk_type = permstring(getasciilabel(d_label));
1008 if (dp && !dp->default_part)
1009 dp->default_part = permstring(getasciilabel(d_label));
1010
1011 if (xp && !xp->disk_type)
1012 xp->disk_type = permstring(getasciilabel(d_label));
1013 if (xp && !xp->default_part)
1014 xp->default_part = permstring(getasciilabel(d_label));
1015
1016 if (xp) {
1017 if (!pdisk_eql(dp, xp)) {
1018 printf("\nWARNING: firmware bug detected:\n\n");
1019 printf("\tdefault: nhead: %ld pcyl: %ld\n",
1020 dp->nhead, dp->pcyl);
1021 printf("\tcurrent: nhead: %ld pcyl: %ld\n\n",
1022 xp->nhead, xp->pcyl);
1023 fbug = TRUE;
1024 }
1025
1026 cur_match = cmp_disk(dp, dp);
1027 tot_match = cmp_disk(xp, dp);
1028
1029 /* if (cur_match > tot_match)*/
1030 if (cur_match != tot_match) {
1031 printf("WARNING: %d current settings differ from default settings.\n\n", cur_match-tot_match);
1032
1033 if (cur_match < tot_match)
1034 printf("cur_match: %d tot_match: %d\n",
1035 cur_match, tot_match);
1036 if (xdebug == 0) {
1037 printf("Mode setting differences:\n");
1038 printf("name: offset in structure: current(1): default(2):\n");
1039
1040 xdebug++;
1041 (void) cmp_disk(xp, dp);
1042 xdebug--;
1043 }
1044 }
1045 }
1046
1047 printf("Enter filename for database prototype [proto.dat]: "); flush();
1048 (void) getline(name, sizeof (name));
1049 if (name[0] == '\0')
1050 strcpy(name, "proto.dat");
1051 if (streql(name, "-"))
1052 f = stdout;
1053 else if ((f = fileopen(name, "rwca")) == NULL)
1054 comerr("Cannot open '%s'.\n", name);
1055
1056 gethostname(hname, sizeof (hname)-1);
1057 hname[sizeof (hname)-1] = '\0';
1058 getdomainname(dname, sizeof (dname)-1);
1059 dname[sizeof (dname)-1] = '\0';
1060
1061 fprintf(f, "#\n# New disk/partition type %s\n# saved by %s@%s%s%s on %s#%s\n",
1062 dp->disk_type,
1063 getlogin(), hname, dname[0] == '.' ? "":".", dname,
1064 datestr(),
1065 fbug?"\n# Remember the Firmware Bug!!! (put correct values into database)\n#":"");
1066
1067 if (!defmodes) {
1068 fprintf(f, "# Warning: entry not generated with default modes\n#\n");
1069 printf("\n*******************\n\n");
1070 printf("Warning the generated prototype file is not derived from default data.\n");
1071 printf("Use -Proto option to get correct values\n");
1072 printf("\n*******************\n\n");
1073 }
1074
1075 if (xp && cur_match > tot_match) {
1076 fprintf(f, "# current data\n");
1077 prdisk(f, xp, scgp->inq);
1078 fprintf(f, "# default data\n");
1079 }
1080 prdisk(f, dp, scgp->inq);
1081 prpartab(f, dp->disk_type, d_label);
1082 checklabel(dp, d_label, 0);
1083 fclose(f);
1084 exit(0);
1085 }
1086