134620Skarels #ifndef lint 2*34667Skarels static char sccsid[] = "@(#)disklabel.c 1.2 (Berkeley/CCI) 06/07/88"; 334620Skarels #endif 434620Skarels 534620Skarels #include "vdfmt.h" 634620Skarels #include "cmd.h" 734620Skarels 834620Skarels int lab_help(); 934620Skarels 1034620Skarels /* 1134620Skarels ** 1234620Skarels */ 1334620Skarels 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; 32*34667Skarels lp->d_ntracks = 23; 33*34667Skarels lp->d_ncylinders = 850; 34*34667Skarels 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 } 47*34667Skarels for (;;) { 48*34667Skarels print("Drive type for controller %d, drive %d? ", ctlr, drive); 49*34667Skarels if (lp->d_typename[0] != 0) 50*34667Skarels printf("(%s) ", lp->d_typename); 51*34667Skarels get_string_cmd(line, lab_help); 52*34667Skarels if (kill_processes == true) 53*34667Skarels return; 54*34667Skarels if (lp->d_typename[0] != 0 && 55*34667Skarels (line[0] == 0 || strcmp(lp->d_typename, line) == 0)) 56*34667Skarels break; 57*34667Skarels if (lp = findproto(line)) 58*34667Skarels break;; 59*34667Skarels if (lp = getdiskbyname(line)) 60*34667Skarels break; 61*34667Skarels if (lp = promptfordisk(line)) 62*34667Skarels break; 63*34667Skarels if (kill_processes == true) 64*34667Skarels return; 65*34667Skarels lp = lab; 66*34667Skarels } 6734620Skarels check: 6834620Skarels plp = findproto(lp->d_typename); 6934620Skarels while (op_mask & FORMAT_OP && 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 * 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 * 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 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]; 21334620Skarels /* 21434620Skarels * Fetch disklabel for disk. 21534620Skarels */ 21634620Skarels readlabel() 21734620Skarels { 21834620Skarels register struct disklabel *lp; 21934620Skarels 22034620Skarels bzero(labelsector, sizeof(labelsector)); 22134620Skarels if (vread(LABELSECTOR, labelsector, 1) < 1) 22234620Skarels return (0); 22334620Skarels for (lp = (struct disklabel *)labelsector; 22434620Skarels lp <= (struct disklabel *)(labelsector+VD_MAXSECSIZE - sizeof(*lp)); 22534620Skarels lp = (struct disklabel *)((char *)lp + 16)) 22634620Skarels if (lp->d_magic == DISKMAGIC && 22734620Skarels lp->d_magic2 == DISKMAGIC) 22834620Skarels break; 22934620Skarels if (lp > (struct disklabel *)(labelsector+VD_MAXSECSIZE-sizeof(*lp)) || 23034620Skarels lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC || 231*34667Skarels dkcksum(lp) != 0) { 232*34667Skarels print("Disk is unlabeled.\n"); 23334620Skarels return (0); 234*34667Skarels } 23534620Skarels *lab = *lp; 23634620Skarels return (1); 23734620Skarels } 23834620Skarels 23934620Skarels writelabel() 24034620Skarels { 24134620Skarels register struct disklabel *lp = lab; 24234620Skarels 24334620Skarels lp->d_magic = DISKMAGIC; 24434620Skarels lp->d_magic2 = DISKMAGIC; 24534620Skarels lp->d_checksum = 0; 24634620Skarels lp->d_checksum = dkcksum(lp); 24734620Skarels if (vwrite(LABELSECTOR, labelsector, 1) != 1) 24834620Skarels printf("error writing disk label\n"); 24934620Skarels } 250