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