1*34620Skarels #ifndef lint
2*34620Skarels static char sccsid[] = "@(#)disklabel.c	1.1 (Berkeley/CCI) 06/02/88";
3*34620Skarels #endif
4*34620Skarels 
5*34620Skarels #include	"vdfmt.h"
6*34620Skarels #include	"cmd.h"
7*34620Skarels 
8*34620Skarels int	lab_help();
9*34620Skarels 
10*34620Skarels /*
11*34620Skarels **
12*34620Skarels */
13*34620Skarels 
14*34620Skarels get_drive_type(ctlr, drive, op_mask)
15*34620Skarels int	ctlr, drive, op_mask;
16*34620Skarels {
17*34620Skarels 	int	tokens[20];
18*34620Skarels 	char	line[132];
19*34620Skarels 	int	savedevflags = 0;
20*34620Skarels 	register struct disklabel *lp;
21*34620Skarels 	struct disklabel *plp, *getdiskbyname(), *promptfordisk(), *findproto();
22*34620Skarels 
23*34620Skarels 	lp = lab;
24*34620Skarels 	if (lp->d_typename[0] == 0) {
25*34620Skarels 		print("Read label from drive %d, controller %d? ", drive, ctlr);
26*34620Skarels 		get_string_cmd(line, lab_help);
27*34620Skarels 		if (kill_processes == true)
28*34620Skarels 			return;
29*34620Skarels 		if (line[0] == 'y' || line[0] == 'Y') {
30*34620Skarels 			lp->d_secsize = 512;
31*34620Skarels 			lp->d_nsectors = 66;
32*34620Skarels 			lp->d_ntracks = 24;
33*34620Skarels 			lp->d_ncylinders = 711;
34*34620Skarels 			lp->d_secpercyl = 66*24;
35*34620Skarels 			if (D_INFO->alive != u_true)
36*34620Skarels 				spin_up_drive();
37*34620Skarels 			savedevflags = lab->d_devflags;
38*34620Skarels 			if (readlabel()) {
39*34620Skarels 				lp->d_devflags = savedevflags;
40*34620Skarels 				lp->d_pat = 0;	/* this can't be what we want */
41*34620Skarels 				goto check;
42*34620Skarels 			}
43*34620Skarels 			lab->d_devflags = savedevflags;
44*34620Skarels 			lp->d_typename[0] = 0;
45*34620Skarels 		}
46*34620Skarels 	}
47*34620Skarels 	print("Drive type for controller %d, drive %d? ", ctlr, drive);
48*34620Skarels 	if (lp->d_typename[0] != 0)
49*34620Skarels 		printf("(%s) ", lp->d_typename);
50*34620Skarels 	get_string_cmd(line, lab_help);
51*34620Skarels 	if (kill_processes == true)
52*34620Skarels 		return;
53*34620Skarels 	if (lp->d_typename[0] != 0 &&
54*34620Skarels 	    (line[0] == 0 || strcmp(lp->d_typename, line) == 0))
55*34620Skarels 		goto check;
56*34620Skarels 	lp = findproto(line);
57*34620Skarels 	while (lp == 0)
58*34620Skarels 		if ((lp = getdiskbyname(line)) == 0) {
59*34620Skarels 			lp = promptfordisk(line);
60*34620Skarels 			if (kill_processes == true)
61*34620Skarels 				return;
62*34620Skarels 		}
63*34620Skarels check:
64*34620Skarels 	plp = findproto(lp->d_typename);
65*34620Skarels 	while (op_mask & FORMAT_OP && lp->d_traksize == 0) {
66*34620Skarels 		print("number of bytes per track");
67*34620Skarels 		if (plp && plp->d_traksize)
68*34620Skarels 			printf(" (%d)", plp->d_traksize);
69*34620Skarels 		printf(": ");
70*34620Skarels 		get_string_cmd(line, lab_help);
71*34620Skarels 		if (kill_processes == true)
72*34620Skarels 			return;
73*34620Skarels 		if (line[0] == 0) {
74*34620Skarels 			if (plp->d_traksize == 0)
75*34620Skarels 				print("no default value\n");
76*34620Skarels 			lp->d_traksize = plp->d_traksize;
77*34620Skarels 		} else
78*34620Skarels 			lp->d_traksize = atol(line);
79*34620Skarels 	}
80*34620Skarels 	print("Drive geometry for controller %d, drive %d (%s):\n",
81*34620Skarels 	    ctlr, drive, lp->d_typename);
82*34620Skarels 	print("  sector size %d; %d sectors, %d tracks, %d cylinders\n",
83*34620Skarels 	    lp->d_secsize, lp->d_nsectors, lp->d_ntracks, lp->d_ncylinders);
84*34620Skarels 	if (lp->d_pat == 0 && op_mask & (FORMAT_OP | VERIFY_OP)) {
85*34620Skarels 		extern struct flawpat defpats, cdcpats;
86*34620Skarels 
87*34620Skarels 		print("media patterns for verify (default or cdc): ");
88*34620Skarels 		get_string_cmd(line, lab_help);
89*34620Skarels 		if (kill_processes == true)
90*34620Skarels 			return;
91*34620Skarels 		if (strcmp(line, "cdc") == 0)
92*34620Skarels 			lp->d_pat = (long) &cdcpats;
93*34620Skarels 		else
94*34620Skarels 			lp->d_pat = (long) &defpats;
95*34620Skarels 	}
96*34620Skarels 	if (lab->d_cylskew == -1)
97*34620Skarels 		lab->d_cylskew = 0;
98*34620Skarels 	if (lab->d_trackskew == -1)
99*34620Skarels 		lab->d_trackskew = 0;
100*34620Skarels 	if (lab->d_sparespertrack == -1)
101*34620Skarels 		lab->d_sparespertrack = 0;
102*34620Skarels 	if (lp != lab) {
103*34620Skarels 		*lab = *lp;
104*34620Skarels 		if (savedevflags)
105*34620Skarels 			lab->d_devflags = savedevflags;
106*34620Skarels 	}
107*34620Skarels 	configure_drive(1);		/* set new parameters */
108*34620Skarels }
109*34620Skarels 
110*34620Skarels struct disklabel *
111*34620Skarels findproto(name)
112*34620Skarels 	char *name;
113*34620Skarels {
114*34620Skarels 	int count;
115*34620Skarels 
116*34620Skarels 	if (C_INFO->type == VDTYPE_VDDC)
117*34620Skarels 		count = smddrives;
118*34620Skarels 	else
119*34620Skarels 		count = 0;
120*34620Skarels 	for (; count < ndrives; count++)
121*34620Skarels 		if (strcmp(vdproto[count].d_typename, name) == 0)
122*34620Skarels 			return (&vdproto[count]);
123*34620Skarels 	return ((struct disklabel *) 0);
124*34620Skarels }
125*34620Skarels 
126*34620Skarels struct disklabel disk;
127*34620Skarels 
128*34620Skarels struct	field {
129*34620Skarels 	char	*f_name;
130*34620Skarels 	char	*f_defaults;
131*34620Skarels 	u_long	*f_location;
132*34620Skarels } fields[] = {
133*34620Skarels 	{ "sector size",		"512",	&disk.d_secsize },
134*34620Skarels 	{ "#sectors/track",		0,	&disk.d_nsectors },
135*34620Skarels 	{ "#tracks/cylinder",		0,	&disk.d_ntracks },
136*34620Skarels 	{ "#cylinders",			0,	&disk.d_ncylinders },
137*34620Skarels 	{ "#bytes/track",		0,	&disk.d_traksize },
138*34620Skarels 	{ 0, 0, 0 },
139*34620Skarels };
140*34620Skarels 
141*34620Skarels struct disklabel *
142*34620Skarels promptfordisk(name)
143*34620Skarels 	char *name;
144*34620Skarels {
145*34620Skarels 	register struct disklabel *dp = &disk;
146*34620Skarels 	register struct field *fp;
147*34620Skarels 	register i;
148*34620Skarels 	char buf[132], *cp;
149*34620Skarels 
150*34620Skarels 	print("%s: unknown drive type\n", name);
151*34620Skarels 	if (get_yes_no("Enter drive parameters") == false)
152*34620Skarels 		return ((struct disklabel *)0);
153*34620Skarels 
154*34620Skarels 	strncpy(dp->d_typename, name, sizeof(dp->d_typename));
155*34620Skarels 	dp->d_type = DTYPE_SMD;
156*34620Skarels 	dp->d_flags = 0;
157*34620Skarels 
158*34620Skarels 	print("(type <cr> to get default value, if only one)\n");
159*34620Skarels 	for (fp = fields; fp->f_name != NULL; fp++) {
160*34620Skarels again:
161*34620Skarels 		print("%s ", fp->f_name);
162*34620Skarels 		if (fp->f_defaults != NULL)
163*34620Skarels 			printf("(%s)", fp->f_defaults);
164*34620Skarels 		printf("? ");
165*34620Skarels 		get_string_cmd(buf, lab_help);
166*34620Skarels 		if (kill_processes == true)
167*34620Skarels 			return ((struct disklabel *)0);
168*34620Skarels 		cp = buf;
169*34620Skarels 		if (*cp == '\0') {
170*34620Skarels 			if (fp->f_defaults == NULL) {
171*34620Skarels 				print("no default value\n");
172*34620Skarels 				goto again;
173*34620Skarels 			}
174*34620Skarels 			cp = fp->f_defaults;
175*34620Skarels 		}
176*34620Skarels 		*fp->f_location = atol(cp);
177*34620Skarels 		if (*fp->f_location == 0) {
178*34620Skarels 			print("%s: bad value\n", cp);
179*34620Skarels 			goto again;
180*34620Skarels 		}
181*34620Skarels 	}
182*34620Skarels 	print("sectors/cylinder (%d)? ", dp->d_nsectors * dp->d_ntracks);
183*34620Skarels 	get_string_cmd(buf, lab_help);
184*34620Skarels 	if (kill_processes == true)
185*34620Skarels 		return ((struct disklabel *)0);
186*34620Skarels 	if (buf[0] == 0)
187*34620Skarels 		dp->d_secpercyl = dp->d_nsectors * dp->d_ntracks;
188*34620Skarels 	else
189*34620Skarels 		dp->d_secpercyl = atol(buf);
190*34620Skarels 	return (dp);
191*34620Skarels }
192*34620Skarels 
193*34620Skarels lab_help()
194*34620Skarels {
195*34620Skarels 	indent();
196*34620Skarels 	print("Entering drive type and parameters:\n");
197*34620Skarels 	indent();
198*34620Skarels 	print("Answer each question with a number or name, as appropriate.\n");
199*34620Skarels 	print("Questions with defaults show them in (parentheses);\n");
200*34620Skarels 	print("press return to accept the default.\n\n");
201*34620Skarels 	exdent(1);
202*34620Skarels 	print("Other commands available:\n");
203*34620Skarels 	indent();
204*34620Skarels 	print("QUIT     - abort current operation\n");
205*34620Skarels 	exdent(2);
206*34620Skarels }
207*34620Skarels 
208*34620Skarels static char labelsector[VD_MAXSECSIZE];
209*34620Skarels /*
210*34620Skarels  * Fetch disklabel for disk.
211*34620Skarels  */
212*34620Skarels readlabel()
213*34620Skarels {
214*34620Skarels 	register struct disklabel *lp;
215*34620Skarels 
216*34620Skarels 	bzero(labelsector, sizeof(labelsector));
217*34620Skarels 	if (vread(LABELSECTOR, labelsector, 1) < 1)
218*34620Skarels 		return (0);
219*34620Skarels 	for (lp = (struct disklabel *)labelsector;
220*34620Skarels 	    lp <= (struct disklabel *)(labelsector+VD_MAXSECSIZE - sizeof(*lp));
221*34620Skarels 	    lp = (struct disklabel *)((char *)lp + 16))
222*34620Skarels 		if (lp->d_magic == DISKMAGIC &&
223*34620Skarels 		    lp->d_magic2 == DISKMAGIC)
224*34620Skarels 			break;
225*34620Skarels 	if (lp > (struct disklabel *)(labelsector+VD_MAXSECSIZE-sizeof(*lp)) ||
226*34620Skarels 	    lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC ||
227*34620Skarels 	    dkcksum(lp) != 0)
228*34620Skarels 		return (0);
229*34620Skarels 	*lab = *lp;
230*34620Skarels 	return (1);
231*34620Skarels }
232*34620Skarels 
233*34620Skarels writelabel()
234*34620Skarels {
235*34620Skarels 	register struct disklabel *lp = lab;
236*34620Skarels 
237*34620Skarels 	lp->d_magic = DISKMAGIC;
238*34620Skarels 	lp->d_magic2 = DISKMAGIC;
239*34620Skarels 	lp->d_checksum = 0;
240*34620Skarels 	lp->d_checksum = dkcksum(lp);
241*34620Skarels 	if (vwrite(LABELSECTOR, labelsector, 1) != 1)
242*34620Skarels 		printf("error writing disk label\n");
243*34620Skarels }
244