129534Ssam #ifndef lint 2*31318Ssam static char sccsid[] = "@(#)proc_cmd.c 1.3 (Berkeley/CCI) 06/01/87"; 329534Ssam #endif 429534Ssam 529534Ssam #include "vdfmt.h" 629534Ssam #include "cmd.h" 729534Ssam 829534Ssam #define RESET 1 929534Ssam #define LIST 2 1029534Ssam #define DELETE 3 1129534Ssam #define FORMAT 4 1229534Ssam #define VERIFY 5 1329534Ssam #define RELOCATE 6 1429534Ssam #define CORRECT 7 1529534Ssam #define INFO 8 1629534Ssam #define PROFILE 9 1729534Ssam #define EXERCISE 10 1829534Ssam #define START 11 1929981Skarels #define EXIT 12 2029534Ssam 2129534Ssam static cmd_text_element commands[] = { 2229534Ssam { RESET, "RESET", "Reinitialize VDFORMAT, and start over" }, 2329981Skarels { EXIT, "EXIT", "Terminate program" }, 2429534Ssam { LIST, "List", "List operations specified so far" }, 2529534Ssam { DELETE, "Delete", "Delete specific operations" }, 2629534Ssam { FORMAT, "Format", "Format and verify disk surface" }, 2729534Ssam { VERIFY, "Verify", "Destructively verify disk surface" }, 2829534Ssam { RELOCATE, "Relocate", "Add known flaws to bad sector map" }, 2929534Ssam { CORRECT, "Correct", "Correct erroneous relocations or drive ID" }, 3029534Ssam { INFO, "Info", "Display known disk information" }, 3129534Ssam { PROFILE, "Profile", "Display seek profile graph of disk" }, 3229534Ssam { EXERCISE, "Exercise", "Perform seek exercises on disk" }, 3329534Ssam { START, "STARt", "Start operations" }, 3429534Ssam { 0, "", "" } 3529534Ssam }; 3629534Ssam 3729534Ssam static cmd_text_element drive_types[20]; 3829534Ssam 3929534Ssam 4029534Ssam /* 4129534Ssam ** 4229534Ssam */ 4329534Ssam 4429534Ssam process_commands() 4529534Ssam { 4629534Ssam int type, tokens[20]; 4729534Ssam int *tok_ptr, count; 4829534Ssam int op_mask = 0; 4929534Ssam char *cptr; 5029534Ssam boolean should_start = false; 5129534Ssam 5229534Ssam for(type=0; type<ndrives; type++) { 5329534Ssam drive_types[type].cmd_token = (int)&vdconfig[type]; 5429534Ssam drive_types[type].cmd_text = vdconfig[type].vc_name; 5529534Ssam drive_types[type].cmd_help = vdconfig[type].vc_type; 5629981Skarels cptr = drive_types[type].cmd_text; 5729981Skarels while(*cptr) { 5829981Skarels *cptr = toupper(*cptr); 5929981Skarels cptr++; 6029981Skarels } 6129534Ssam } 6229534Ssam drive_types[type].cmd_token = 0; 6329534Ssam for(;;) { 6429534Ssam cur.state = cmd; 6529534Ssam kill_processes = false; 6629534Ssam exdent(-1); 6729534Ssam op_mask = 0; 6829534Ssam printf("vdformat> "); 6929534Ssam count = get_text_cmd(commands, tokens); 7029534Ssam if(kill_processes == true) 7129534Ssam _longjmp(quit_environ, 1); 7229534Ssam tok_ptr = tokens; 7329534Ssam if((*tok_ptr == 0) || !count) 7429534Ssam continue; 7529534Ssam while(*tok_ptr) { 7629534Ssam switch (*tok_ptr) { 7729534Ssam case RESET : 7829534Ssam reset(); 7929534Ssam break; 8029534Ssam case LIST : 8129534Ssam list(); 8229534Ssam break; 8329534Ssam case DELETE : 8429534Ssam delete(); 8529534Ssam break; 8629534Ssam case FORMAT : 8729534Ssam op_mask |= FORMAT_OP; 8829534Ssam break; 8929534Ssam case VERIFY : 9029534Ssam op_mask |= VERIFY_OP; 9129534Ssam break; 9229534Ssam case RELOCATE : 9329534Ssam op_mask |= RELOCATE_OP; 9429534Ssam break; 9529534Ssam case CORRECT : 9629534Ssam op_mask |= CORRECT_OP; 9729534Ssam break; 9829534Ssam case INFO : 9929534Ssam op_mask |= INFO_OP; 10029534Ssam break; 10129534Ssam case PROFILE : 10229534Ssam op_mask |= PROFILE_OP; 10329534Ssam break; 10429534Ssam case EXERCISE : 10529534Ssam op_mask |= EXERCISE_OP; 10629534Ssam break; 10729534Ssam case START : 10829534Ssam should_start = true; 10929534Ssam break; 11029981Skarels case EXIT: 11129981Skarels exit(0); 11229981Skarels /*NOTREACHED*/ 11329534Ssam default: /* ignore */ 11429534Ssam break; 11529534Ssam } 11629534Ssam tok_ptr++; 11729534Ssam } 11829534Ssam if(op_mask) { 11929534Ssam get_drive_parameters(op_mask); 12029534Ssam } 12129534Ssam if(should_start) { 12229534Ssam start_commands(); 12329534Ssam should_start = false; 12429534Ssam } 12529534Ssam } 12629534Ssam } 12729534Ssam 12829534Ssam 12929534Ssam /* 13029534Ssam ** 13129534Ssam */ 13229534Ssam 13329534Ssam static boolean header_printed = false; 13429534Ssam 13529534Ssam get_drive_parameters(op_mask) 13629534Ssam int op_mask; 13729534Ssam { 13829534Ssam int c_list[20], i, num_pat; 13929534Ssam 14029534Ssam indent(); 14129534Ssam header_printed = false; 14229534Ssam get_ctlr_list(c_list, op_mask); 14329534Ssam if(kill_processes == true) { 14429534Ssam kill_processes = false; 14529534Ssam c_list[0]= -1; 14629534Ssam } 14729534Ssam for(i=0; c_list[i] != -1; i++) { 14829534Ssam int d_list[40], j; 14929534Ssam 15029534Ssam indent(); 15129534Ssam get_drive_list(c_list[i], d_list, op_mask); 15229534Ssam if(kill_processes == true) { 15329534Ssam kill_processes = false; 15429534Ssam break; 15529534Ssam } 15629534Ssam indent(); 15729534Ssam if(op_mask & (FORMAT_OP | VERIFY_OP)) { 15829534Ssam num_pat = get_num_pat(); 15929534Ssam if(kill_processes == true) { 16029534Ssam kill_processes = false; 16129534Ssam break; 16229534Ssam } 16329534Ssam } 16429534Ssam for(j=0; d_list[j] != -1; j++) { 16529534Ssam get_drive_type(c_list[i], d_list[j]); 16629534Ssam if(kill_processes == true) { 16729534Ssam kill_processes = false; 16829534Ssam break; 16929534Ssam } 17029534Ssam if(op_mask & ~INFO_OP) { 17129534Ssam indent(); 17229534Ssam get_drive_id(c_list[i], d_list[j]); 17329534Ssam if(kill_processes == true) { 17429534Ssam kill_processes = false; 17529534Ssam break; 17629534Ssam } 17729534Ssam exdent(1); 17829534Ssam } 17929534Ssam ops_to_do[c_list[i]][d_list[j]].op |= op_mask; 18029534Ssam if(op_mask & (FORMAT_OP | VERIFY_OP)) 18129534Ssam ops_to_do[c_list[i]][d_list[j]].numpat=num_pat; 18229534Ssam } 18329534Ssam exdent(1); 18429534Ssam } 18529534Ssam exdent(2); 18629534Ssam } 18729534Ssam 18829534Ssam /* 18929534Ssam ** 19029534Ssam */ 19129534Ssam 19229534Ssam get_ctlr_list(c_list, op_mask) 19329534Ssam int *c_list, op_mask; 19429534Ssam { 19529534Ssam extern int ctlr_help(); 19629534Ssam register int i, ctlr; 19729534Ssam int table[MAXCTLR+10]; 19829534Ssam 19929534Ssam i = 0; 20029534Ssam for(ctlr=0; ctlr<MAXCTLR; ctlr++) 20129534Ssam if(c_info[ctlr].alive == u_true) 20229534Ssam table[i++] = ctlr; 20329534Ssam table[i] = -1; 20429534Ssam /* If only one controller is possible don't ask */ 20529534Ssam if(table[1] == -1) { 20629534Ssam *c_list++ = table[0]; 20729534Ssam *c_list = -1; 20829534Ssam return; 20929534Ssam } 21029534Ssam for(;;) { 21129534Ssam header_printed = true; 21229534Ssam print(""); /* Force indent */ 21329534Ssam print_op_list(op_mask); 21429534Ssam printf(" on which controllers? "); 21529534Ssam get_digit_list(c_list, table, ctlr_help); 21629534Ssam if(kill_processes == true) 21729534Ssam return; 21829534Ssam if(*c_list != -1) 21929534Ssam break; 22029534Ssam } 22129534Ssam } 22229534Ssam 22329534Ssam 22429534Ssam /* 22529534Ssam ** 22629534Ssam */ 22729534Ssam 22829534Ssam ctlr_help() 22929534Ssam { 23029534Ssam register int ctlr; 23129534Ssam 23229534Ssam indent(); 23329534Ssam print("The following controllers are attached to the system:\n"); 23429534Ssam indent(); 23529534Ssam for(ctlr=0; ctlr<MAXCTLR; ctlr++) 23629534Ssam if(c_info[ctlr].alive == u_true) { 23729534Ssam print("Controller %d, which is a%s %s controller.\n", 23829534Ssam ctlr, (c_info[ctlr].name[0] == 'S') ? "n" : "", 23929534Ssam c_info[ctlr].name); 24029534Ssam } 24129534Ssam print("\n"); 24229534Ssam exdent(2); 24329534Ssam } 24429534Ssam 24529534Ssam static int max_drive = 0; 24629534Ssam 24729534Ssam /* 24829534Ssam ** 24929534Ssam */ 25029534Ssam 25129534Ssam get_drive_list(ctlr, d_list, op_mask) 25229534Ssam int ctlr, *d_list, op_mask; 25329534Ssam { 25429534Ssam extern int drive_help(); 25529534Ssam int table[MAXDRIVE+10]; 25629534Ssam int i; 25729534Ssam 258*31318Ssam max_drive = (c_info[ctlr].type == VDTYPE_VDDC) ? 4 : 16; 25929534Ssam for(i=0; i<max_drive; i++) 26029534Ssam table[i] = i; 26129534Ssam table[i] = -1; 26229534Ssam for(;;) { 26329534Ssam if(header_printed == true) 26429534Ssam print("Drives on controller %d? ", ctlr); 26529534Ssam else { 26629534Ssam header_printed = true; 26729534Ssam print(""); /* Force indent */ 26829534Ssam print_op_list(op_mask); 26929534Ssam printf(" on which drives? "); 27029534Ssam } 27129534Ssam get_digit_list(d_list, table, drive_help); 27229534Ssam if(kill_processes == true) 27329534Ssam return; 27429534Ssam if(*d_list != -1) 27529534Ssam break; 27629534Ssam } 27729534Ssam } 27829534Ssam 27929534Ssam 28029534Ssam /* 28129534Ssam ** 28229534Ssam */ 28329534Ssam 28429534Ssam get_drive_type(ctlr, drive) 28529534Ssam int ctlr, drive; 28629534Ssam { 28729534Ssam int tokens[20]; 28829534Ssam int count; 28929534Ssam 29029534Ssam for(;;) { 29129534Ssam print("Drive type for controller %d, drive %d? ", ctlr, drive); 29229534Ssam if(d_info[ctlr][drive].info != 0) 29329534Ssam printf("(%s) ", d_info[ctlr][drive].info->vc_name); 294*31318Ssam if(c_info[ctlr].type == VDTYPE_VDDC) 29529981Skarels count = get_text_cmd(drive_types+smddrives, tokens); 29629534Ssam else 29729534Ssam count = get_text_cmd(drive_types, tokens); 29829534Ssam if(kill_processes == true) 29929534Ssam return; 30029534Ssam if(!*tokens && (d_info[ctlr][drive].info != 0) && !count) 30129534Ssam break; 30229534Ssam if(d_info[ctlr][drive].info = (struct vdconfig *)*tokens) 30329534Ssam break; 30429534Ssam } 30529534Ssam } 30629534Ssam 30729534Ssam 30829534Ssam 30929534Ssam /* 31029534Ssam ** 31129534Ssam */ 31229534Ssam 31329534Ssam id_help() 31429534Ssam { 31529534Ssam indent(); 31629534Ssam print("The following commands are available:\n"); 31729534Ssam indent(); 31829534Ssam print("STATus - Display formatter state.\n"); 31929534Ssam print("QUIT - Terminate current operation.\n"); 32029534Ssam print(""); 32129534Ssam print("A module serial can be any number greater than zero.\n"); 32229534Ssam exdent(2); 32329534Ssam } 32429534Ssam 32529534Ssam 32629534Ssam /* 32729534Ssam ** 32829534Ssam */ 32929534Ssam 33029534Ssam get_drive_id(ctlr, drive) 33129534Ssam int ctlr, drive; 33229534Ssam { 33329534Ssam int new_id; 33429534Ssam 33529534Ssam for(;;) { 33629534Ssam print("Module serial number for controller %d, drive %d? ", 33729534Ssam ctlr, drive); 33829534Ssam if(d_info[ctlr][drive].id != -1) 33929534Ssam printf("(%d) ", d_info[ctlr][drive].id); 34029534Ssam new_id = get_digit_cmd(id_help); 34129534Ssam if(new_id > 0) { 34229534Ssam d_info[ctlr][drive].id = new_id; 34329534Ssam break; 34429534Ssam } 34529534Ssam else if(d_info[ctlr][drive].id != -1) 34629534Ssam break; 34729534Ssam } 34829534Ssam } 34929534Ssam 35029534Ssam 35129534Ssam /* 35229534Ssam ** 35329534Ssam */ 35429534Ssam 35529534Ssam drive_help() 35629534Ssam { 35729534Ssam indent(); 35829534Ssam print("Drive numbers 0 through %d may be entered.\n", max_drive-1); 35929534Ssam exdent(1); 36029534Ssam } 36129534Ssam 36229534Ssam 36329534Ssam /* 36429534Ssam ** 36529534Ssam */ 36629534Ssam 36729534Ssam pat_help() 36829534Ssam { 36929534Ssam indent(); 37029534Ssam print("Between 0 and 16 patterns may be used while verifying.\n"); 37129534Ssam exdent(1); 37229534Ssam } 37329534Ssam 37429534Ssam 37529534Ssam /* 37629534Ssam ** 37729534Ssam */ 37829534Ssam 37929534Ssam get_num_pat() 38029534Ssam { 38129534Ssam int table[17+10]; 38229534Ssam int results[17+10]; 38329534Ssam int i; 38429534Ssam 38529534Ssam for(i=0; i<=16; i++) 38629534Ssam table[i] = i; 38729534Ssam table[i] = -1; 38829534Ssam for(;;) { 38929534Ssam print("Number of patterns to use while verifying? "); 39029534Ssam get_digit_list(results, table, pat_help); 39129534Ssam if(kill_processes == true) 39229534Ssam return 0; 39329534Ssam if(results[0] != -1) 39429534Ssam break; 39529534Ssam } 39629534Ssam return results[0]; 39729534Ssam } 39829534Ssam 399