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