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