1 #ifndef lint 2 static char sccsid[] = "@(#)proc_cmd.c 1.2 (Berkeley/CCI) 11/04/86"; 3 #endif 4 5 #include "vdfmt.h" 6 #include "cmd.h" 7 8 #define RESET 1 9 #define LIST 2 10 #define DELETE 3 11 #define FORMAT 4 12 #define VERIFY 5 13 #define RELOCATE 6 14 #define CORRECT 7 15 #define INFO 8 16 #define PROFILE 9 17 #define EXERCISE 10 18 #define START 11 19 #define EXIT 12 20 21 static cmd_text_element commands[] = { 22 { RESET, "RESET", "Reinitialize VDFORMAT, and start over" }, 23 { EXIT, "EXIT", "Terminate program" }, 24 { LIST, "List", "List operations specified so far" }, 25 { DELETE, "Delete", "Delete specific operations" }, 26 { FORMAT, "Format", "Format and verify disk surface" }, 27 { VERIFY, "Verify", "Destructively verify disk surface" }, 28 { RELOCATE, "Relocate", "Add known flaws to bad sector map" }, 29 { CORRECT, "Correct", "Correct erroneous relocations or drive ID" }, 30 { INFO, "Info", "Display known disk information" }, 31 { PROFILE, "Profile", "Display seek profile graph of disk" }, 32 { EXERCISE, "Exercise", "Perform seek exercises on disk" }, 33 { START, "STARt", "Start operations" }, 34 { 0, "", "" } 35 }; 36 37 static cmd_text_element drive_types[20]; 38 39 40 /* 41 ** 42 */ 43 44 process_commands() 45 { 46 int type, tokens[20]; 47 int *tok_ptr, count; 48 int op_mask = 0; 49 char *cptr; 50 boolean should_start = false; 51 52 for(type=0; type<ndrives; type++) { 53 drive_types[type].cmd_token = (int)&vdconfig[type]; 54 drive_types[type].cmd_text = vdconfig[type].vc_name; 55 drive_types[type].cmd_help = vdconfig[type].vc_type; 56 cptr = drive_types[type].cmd_text; 57 while(*cptr) { 58 *cptr = toupper(*cptr); 59 cptr++; 60 } 61 } 62 drive_types[type].cmd_token = 0; 63 for(;;) { 64 cur.state = cmd; 65 kill_processes = false; 66 exdent(-1); 67 op_mask = 0; 68 printf("vdformat> "); 69 count = get_text_cmd(commands, tokens); 70 if(kill_processes == true) 71 _longjmp(quit_environ, 1); 72 tok_ptr = tokens; 73 if((*tok_ptr == 0) || !count) 74 continue; 75 while(*tok_ptr) { 76 switch (*tok_ptr) { 77 case RESET : 78 reset(); 79 break; 80 case LIST : 81 list(); 82 break; 83 case DELETE : 84 delete(); 85 break; 86 case FORMAT : 87 op_mask |= FORMAT_OP; 88 break; 89 case VERIFY : 90 op_mask |= VERIFY_OP; 91 break; 92 case RELOCATE : 93 op_mask |= RELOCATE_OP; 94 break; 95 case CORRECT : 96 op_mask |= CORRECT_OP; 97 break; 98 case INFO : 99 op_mask |= INFO_OP; 100 break; 101 case PROFILE : 102 op_mask |= PROFILE_OP; 103 break; 104 case EXERCISE : 105 op_mask |= EXERCISE_OP; 106 break; 107 case START : 108 should_start = true; 109 break; 110 case EXIT: 111 exit(0); 112 /*NOTREACHED*/ 113 default: /* ignore */ 114 break; 115 } 116 tok_ptr++; 117 } 118 if(op_mask) { 119 get_drive_parameters(op_mask); 120 } 121 if(should_start) { 122 start_commands(); 123 should_start = false; 124 } 125 } 126 } 127 128 129 /* 130 ** 131 */ 132 133 static boolean header_printed = false; 134 135 get_drive_parameters(op_mask) 136 int op_mask; 137 { 138 int c_list[20], i, num_pat; 139 140 indent(); 141 header_printed = false; 142 get_ctlr_list(c_list, op_mask); 143 if(kill_processes == true) { 144 kill_processes = false; 145 c_list[0]= -1; 146 } 147 for(i=0; c_list[i] != -1; i++) { 148 int d_list[40], j; 149 150 indent(); 151 get_drive_list(c_list[i], d_list, op_mask); 152 if(kill_processes == true) { 153 kill_processes = false; 154 break; 155 } 156 indent(); 157 if(op_mask & (FORMAT_OP | VERIFY_OP)) { 158 num_pat = get_num_pat(); 159 if(kill_processes == true) { 160 kill_processes = false; 161 break; 162 } 163 } 164 for(j=0; d_list[j] != -1; j++) { 165 get_drive_type(c_list[i], d_list[j]); 166 if(kill_processes == true) { 167 kill_processes = false; 168 break; 169 } 170 if(op_mask & ~INFO_OP) { 171 indent(); 172 get_drive_id(c_list[i], d_list[j]); 173 if(kill_processes == true) { 174 kill_processes = false; 175 break; 176 } 177 exdent(1); 178 } 179 ops_to_do[c_list[i]][d_list[j]].op |= op_mask; 180 if(op_mask & (FORMAT_OP | VERIFY_OP)) 181 ops_to_do[c_list[i]][d_list[j]].numpat=num_pat; 182 } 183 exdent(1); 184 } 185 exdent(2); 186 } 187 188 /* 189 ** 190 */ 191 192 get_ctlr_list(c_list, op_mask) 193 int *c_list, op_mask; 194 { 195 extern int ctlr_help(); 196 register int i, ctlr; 197 int table[MAXCTLR+10]; 198 199 i = 0; 200 for(ctlr=0; ctlr<MAXCTLR; ctlr++) 201 if(c_info[ctlr].alive == u_true) 202 table[i++] = ctlr; 203 table[i] = -1; 204 /* If only one controller is possible don't ask */ 205 if(table[1] == -1) { 206 *c_list++ = table[0]; 207 *c_list = -1; 208 return; 209 } 210 for(;;) { 211 header_printed = true; 212 print(""); /* Force indent */ 213 print_op_list(op_mask); 214 printf(" on which controllers? "); 215 get_digit_list(c_list, table, ctlr_help); 216 if(kill_processes == true) 217 return; 218 if(*c_list != -1) 219 break; 220 } 221 } 222 223 224 /* 225 ** 226 */ 227 228 ctlr_help() 229 { 230 register int ctlr; 231 232 indent(); 233 print("The following controllers are attached to the system:\n"); 234 indent(); 235 for(ctlr=0; ctlr<MAXCTLR; ctlr++) 236 if(c_info[ctlr].alive == u_true) { 237 print("Controller %d, which is a%s %s controller.\n", 238 ctlr, (c_info[ctlr].name[0] == 'S') ? "n" : "", 239 c_info[ctlr].name); 240 } 241 print("\n"); 242 exdent(2); 243 } 244 245 static int max_drive = 0; 246 247 /* 248 ** 249 */ 250 251 get_drive_list(ctlr, d_list, op_mask) 252 int ctlr, *d_list, op_mask; 253 { 254 extern int drive_help(); 255 int table[MAXDRIVE+10]; 256 int i; 257 258 max_drive = (c_info[ctlr].type == SMDCTLR) ? 4 : 16; 259 for(i=0; i<max_drive; i++) 260 table[i] = i; 261 table[i] = -1; 262 for(;;) { 263 if(header_printed == true) 264 print("Drives on controller %d? ", ctlr); 265 else { 266 header_printed = true; 267 print(""); /* Force indent */ 268 print_op_list(op_mask); 269 printf(" on which drives? "); 270 } 271 get_digit_list(d_list, table, drive_help); 272 if(kill_processes == true) 273 return; 274 if(*d_list != -1) 275 break; 276 } 277 } 278 279 280 /* 281 ** 282 */ 283 284 get_drive_type(ctlr, drive) 285 int ctlr, drive; 286 { 287 int tokens[20]; 288 int count; 289 290 for(;;) { 291 print("Drive type for controller %d, drive %d? ", ctlr, drive); 292 if(d_info[ctlr][drive].info != 0) 293 printf("(%s) ", d_info[ctlr][drive].info->vc_name); 294 if(c_info[ctlr].type == SMDCTLR) 295 count = get_text_cmd(drive_types+smddrives, tokens); 296 else 297 count = get_text_cmd(drive_types, tokens); 298 if(kill_processes == true) 299 return; 300 if(!*tokens && (d_info[ctlr][drive].info != 0) && !count) 301 break; 302 if(d_info[ctlr][drive].info = (struct vdconfig *)*tokens) 303 break; 304 } 305 } 306 307 308 309 /* 310 ** 311 */ 312 313 id_help() 314 { 315 indent(); 316 print("The following commands are available:\n"); 317 indent(); 318 print("STATus - Display formatter state.\n"); 319 print("QUIT - Terminate current operation.\n"); 320 print(""); 321 print("A module serial can be any number greater than zero.\n"); 322 exdent(2); 323 } 324 325 326 /* 327 ** 328 */ 329 330 get_drive_id(ctlr, drive) 331 int ctlr, drive; 332 { 333 int new_id; 334 335 for(;;) { 336 print("Module serial number for controller %d, drive %d? ", 337 ctlr, drive); 338 if(d_info[ctlr][drive].id != -1) 339 printf("(%d) ", d_info[ctlr][drive].id); 340 new_id = get_digit_cmd(id_help); 341 if(new_id > 0) { 342 d_info[ctlr][drive].id = new_id; 343 break; 344 } 345 else if(d_info[ctlr][drive].id != -1) 346 break; 347 } 348 } 349 350 351 /* 352 ** 353 */ 354 355 drive_help() 356 { 357 indent(); 358 print("Drive numbers 0 through %d may be entered.\n", max_drive-1); 359 exdent(1); 360 } 361 362 363 /* 364 ** 365 */ 366 367 pat_help() 368 { 369 indent(); 370 print("Between 0 and 16 patterns may be used while verifying.\n"); 371 exdent(1); 372 } 373 374 375 /* 376 ** 377 */ 378 379 get_num_pat() 380 { 381 int table[17+10]; 382 int results[17+10]; 383 int i; 384 385 for(i=0; i<=16; i++) 386 table[i] = i; 387 table[i] = -1; 388 for(;;) { 389 print("Number of patterns to use while verifying? "); 390 get_digit_list(results, table, pat_help); 391 if(kill_processes == true) 392 return 0; 393 if(results[0] != -1) 394 break; 395 } 396 return results[0]; 397 } 398 399