134620Skarels #ifndef lint
2*43645Skarels static char sccsid[] = "@(#)disklabel.c	1.3 (Berkeley/CCI) 06/24/90";
334620Skarels #endif
434620Skarels 
534620Skarels #include	"vdfmt.h"
634620Skarels #include	"cmd.h"
734620Skarels 
834620Skarels int	lab_help();
934620Skarels 
1034620Skarels /*
1134620Skarels **
1234620Skarels */
1334620Skarels 
get_drive_type(ctlr,drive,op_mask)1434620Skarels get_drive_type(ctlr, drive, op_mask)
1534620Skarels int	ctlr, drive, op_mask;
1634620Skarels {
1734620Skarels 	int	tokens[20];
1834620Skarels 	char	line[132];
1934620Skarels 	int	savedevflags = 0;
2034620Skarels 	register struct disklabel *lp;
2134620Skarels 	struct disklabel *plp, *getdiskbyname(), *promptfordisk(), *findproto();
2234620Skarels 
2334620Skarels 	lp = lab;
2434620Skarels 	if (lp->d_typename[0] == 0) {
2534620Skarels 		print("Read label from drive %d, controller %d? ", drive, ctlr);
2634620Skarels 		get_string_cmd(line, lab_help);
2734620Skarels 		if (kill_processes == true)
2834620Skarels 			return;
2934620Skarels 		if (line[0] == 'y' || line[0] == 'Y') {
3034620Skarels 			lp->d_secsize = 512;
3134620Skarels 			lp->d_nsectors = 66;
3234667Skarels 			lp->d_ntracks = 23;
3334667Skarels 			lp->d_ncylinders = 850;
3434667Skarels 			lp->d_secpercyl = 66*23;
3534620Skarels 			if (D_INFO->alive != u_true)
3634620Skarels 				spin_up_drive();
3734620Skarels 			savedevflags = lab->d_devflags;
3834620Skarels 			if (readlabel()) {
3934620Skarels 				lp->d_devflags = savedevflags;
4034620Skarels 				lp->d_pat = 0;	/* this can't be what we want */
4134620Skarels 				goto check;
4234620Skarels 			}
4334620Skarels 			lab->d_devflags = savedevflags;
4434620Skarels 			lp->d_typename[0] = 0;
4534620Skarels 		}
4634620Skarels 	}
4734667Skarels 	for (;;) {
4834667Skarels 		print("Drive type for controller %d, drive %d? ", ctlr, drive);
4934667Skarels 		if (lp->d_typename[0] != 0)
5034667Skarels 			printf("(%s) ", lp->d_typename);
5134667Skarels 		get_string_cmd(line, lab_help);
5234667Skarels 		if (kill_processes == true)
5334667Skarels 			return;
5434667Skarels 		if (lp->d_typename[0] != 0 &&
5534667Skarels 		    (line[0] == 0 || strcmp(lp->d_typename, line) == 0))
5634667Skarels 			break;
5734667Skarels 		if (lp = findproto(line))
5834667Skarels 			break;;
5934667Skarels 		if (lp = getdiskbyname(line))
6034667Skarels 			break;
6134667Skarels 		if (lp = promptfordisk(line))
6234667Skarels 			break;
6334667Skarels 		if (kill_processes == true)
6434667Skarels 			return;
6534667Skarels 		lp = lab;
6634667Skarels 	}
6734620Skarels check:
6834620Skarels 	plp = findproto(lp->d_typename);
69*43645Skarels 	while (lp->d_traksize == 0) {
7034620Skarels 		print("number of bytes per track");
7134620Skarels 		if (plp && plp->d_traksize)
7234620Skarels 			printf(" (%d)", plp->d_traksize);
7334620Skarels 		printf(": ");
7434620Skarels 		get_string_cmd(line, lab_help);
7534620Skarels 		if (kill_processes == true)
7634620Skarels 			return;
7734620Skarels 		if (line[0] == 0) {
7834620Skarels 			if (plp->d_traksize == 0)
7934620Skarels 				print("no default value\n");
8034620Skarels 			lp->d_traksize = plp->d_traksize;
8134620Skarels 		} else
8234620Skarels 			lp->d_traksize = atol(line);
8334620Skarels 	}
8434620Skarels 	print("Drive geometry for controller %d, drive %d (%s):\n",
8534620Skarels 	    ctlr, drive, lp->d_typename);
8634620Skarels 	print("  sector size %d; %d sectors, %d tracks, %d cylinders\n",
8734620Skarels 	    lp->d_secsize, lp->d_nsectors, lp->d_ntracks, lp->d_ncylinders);
8834620Skarels 	if (lp->d_pat == 0 && op_mask & (FORMAT_OP | VERIFY_OP)) {
8934620Skarels 		extern struct flawpat defpats, cdcpats;
9034620Skarels 
9134620Skarels 		print("media patterns for verify (default or cdc): ");
9234620Skarels 		get_string_cmd(line, lab_help);
9334620Skarels 		if (kill_processes == true)
9434620Skarels 			return;
9534620Skarels 		if (strcmp(line, "cdc") == 0)
9634620Skarels 			lp->d_pat = (long) &cdcpats;
9734620Skarels 		else
9834620Skarels 			lp->d_pat = (long) &defpats;
9934620Skarels 	}
10034620Skarels 	if (lab->d_cylskew == -1)
10134620Skarels 		lab->d_cylskew = 0;
10234620Skarels 	if (lab->d_trackskew == -1)
10334620Skarels 		lab->d_trackskew = 0;
10434620Skarels 	if (lab->d_sparespertrack == -1)
10534620Skarels 		lab->d_sparespertrack = 0;
10634620Skarels 	if (lp != lab) {
10734620Skarels 		*lab = *lp;
10834620Skarels 		if (savedevflags)
10934620Skarels 			lab->d_devflags = savedevflags;
11034620Skarels 	}
11134620Skarels 	configure_drive(1);		/* set new parameters */
11234620Skarels }
11334620Skarels 
11434620Skarels struct disklabel *
findproto(name)11534620Skarels findproto(name)
11634620Skarels 	char *name;
11734620Skarels {
11834620Skarels 	int count;
11934620Skarels 
12034620Skarels 	if (C_INFO->type == VDTYPE_VDDC)
12134620Skarels 		count = smddrives;
12234620Skarels 	else
12334620Skarels 		count = 0;
12434620Skarels 	for (; count < ndrives; count++)
12534620Skarels 		if (strcmp(vdproto[count].d_typename, name) == 0)
12634620Skarels 			return (&vdproto[count]);
12734620Skarels 	return ((struct disklabel *) 0);
12834620Skarels }
12934620Skarels 
13034620Skarels struct disklabel disk;
13134620Skarels 
13234620Skarels struct	field {
13334620Skarels 	char	*f_name;
13434620Skarels 	char	*f_defaults;
13534620Skarels 	u_long	*f_location;
13634620Skarels } fields[] = {
13734620Skarels 	{ "sector size",		"512",	&disk.d_secsize },
13834620Skarels 	{ "#sectors/track",		0,	&disk.d_nsectors },
13934620Skarels 	{ "#tracks/cylinder",		0,	&disk.d_ntracks },
14034620Skarels 	{ "#cylinders",			0,	&disk.d_ncylinders },
14134620Skarels 	{ "#bytes/track",		0,	&disk.d_traksize },
14234620Skarels 	{ 0, 0, 0 },
14334620Skarels };
14434620Skarels 
14534620Skarels struct disklabel *
promptfordisk(name)14634620Skarels promptfordisk(name)
14734620Skarels 	char *name;
14834620Skarels {
14934620Skarels 	register struct disklabel *dp = &disk;
15034620Skarels 	register struct field *fp;
15134620Skarels 	register i;
15234620Skarels 	char buf[132], *cp;
15334620Skarels 
15434620Skarels 	print("%s: unknown drive type\n", name);
15534620Skarels 	if (get_yes_no("Enter drive parameters") == false)
15634620Skarels 		return ((struct disklabel *)0);
15734620Skarels 
15834620Skarels 	strncpy(dp->d_typename, name, sizeof(dp->d_typename));
15934620Skarels 	dp->d_type = DTYPE_SMD;
16034620Skarels 	dp->d_flags = 0;
16134620Skarels 
16234620Skarels 	print("(type <cr> to get default value, if only one)\n");
16334620Skarels 	for (fp = fields; fp->f_name != NULL; fp++) {
16434620Skarels again:
16534620Skarels 		print("%s ", fp->f_name);
16634620Skarels 		if (fp->f_defaults != NULL)
16734620Skarels 			printf("(%s)", fp->f_defaults);
16834620Skarels 		printf("? ");
16934620Skarels 		get_string_cmd(buf, lab_help);
17034620Skarels 		if (kill_processes == true)
17134620Skarels 			return ((struct disklabel *)0);
17234620Skarels 		cp = buf;
17334620Skarels 		if (*cp == '\0') {
17434620Skarels 			if (fp->f_defaults == NULL) {
17534620Skarels 				print("no default value\n");
17634620Skarels 				goto again;
17734620Skarels 			}
17834620Skarels 			cp = fp->f_defaults;
17934620Skarels 		}
18034620Skarels 		*fp->f_location = atol(cp);
18134620Skarels 		if (*fp->f_location == 0) {
18234620Skarels 			print("%s: bad value\n", cp);
18334620Skarels 			goto again;
18434620Skarels 		}
18534620Skarels 	}
18634620Skarels 	print("sectors/cylinder (%d)? ", dp->d_nsectors * dp->d_ntracks);
18734620Skarels 	get_string_cmd(buf, lab_help);
18834620Skarels 	if (kill_processes == true)
18934620Skarels 		return ((struct disklabel *)0);
19034620Skarels 	if (buf[0] == 0)
19134620Skarels 		dp->d_secpercyl = dp->d_nsectors * dp->d_ntracks;
19234620Skarels 	else
19334620Skarels 		dp->d_secpercyl = atol(buf);
19434620Skarels 	return (dp);
19534620Skarels }
19634620Skarels 
lab_help()19734620Skarels lab_help()
19834620Skarels {
19934620Skarels 	indent();
20034620Skarels 	print("Entering drive type and parameters:\n");
20134620Skarels 	indent();
20234620Skarels 	print("Answer each question with a number or name, as appropriate.\n");
20334620Skarels 	print("Questions with defaults show them in (parentheses);\n");
20434620Skarels 	print("press return to accept the default.\n\n");
20534620Skarels 	exdent(1);
20634620Skarels 	print("Other commands available:\n");
20734620Skarels 	indent();
20834620Skarels 	print("QUIT     - abort current operation\n");
20934620Skarels 	exdent(2);
21034620Skarels }
21134620Skarels 
21234620Skarels static char labelsector[VD_MAXSECSIZE];
213*43645Skarels 
21434620Skarels /*
21534620Skarels  * Fetch disklabel for disk.
21634620Skarels  */
readlabel()21734620Skarels readlabel()
21834620Skarels {
21934620Skarels 	register struct disklabel *lp;
22034620Skarels 
22134620Skarels 	bzero(labelsector, sizeof(labelsector));
22234620Skarels 	if (vread(LABELSECTOR, labelsector, 1) < 1)
22334620Skarels 		return (0);
22434620Skarels 	for (lp = (struct disklabel *)labelsector;
22534620Skarels 	    lp <= (struct disklabel *)(labelsector+VD_MAXSECSIZE - sizeof(*lp));
22634620Skarels 	    lp = (struct disklabel *)((char *)lp + 16))
22734620Skarels 		if (lp->d_magic == DISKMAGIC &&
22834620Skarels 		    lp->d_magic2 == DISKMAGIC)
22934620Skarels 			break;
23034620Skarels 	if (lp > (struct disklabel *)(labelsector+VD_MAXSECSIZE-sizeof(*lp)) ||
23134620Skarels 	    lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC ||
23234667Skarels 	    dkcksum(lp) != 0) {
23334667Skarels 		print("Disk is unlabeled.\n");
23434620Skarels 		return (0);
23534667Skarels 	}
23634620Skarels 	*lab = *lp;
23734620Skarels 	return (1);
23834620Skarels }
23934620Skarels 
writelabel()24034620Skarels writelabel()
24134620Skarels {
242*43645Skarels 	register struct disklabel *lp;
24334620Skarels 
244*43645Skarels 	bzero(labelsector, sizeof(labelsector));
245*43645Skarels 	lp = (struct disklabel *)(labelsector + LABELOFFSET);
246*43645Skarels 	*lp = *lab;
24734620Skarels 	lp->d_magic = DISKMAGIC;
24834620Skarels 	lp->d_magic2 = DISKMAGIC;
24934620Skarels 	lp->d_checksum = 0;
25034620Skarels 	lp->d_checksum = dkcksum(lp);
25134620Skarels 	if (vwrite(LABELSECTOR, labelsector, 1) != 1)
25234620Skarels 		printf("error writing disk label\n");
25334620Skarels }
254