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