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