1 #ifndef lint
2 static char sccsid[] = "@(#)proc_cmd.c 1.4 (Berkeley/CCI) 11/23/87";
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
38 /*
39 **
40 */
41
process_commands()42 process_commands()
43 {
44 int tokens[20];
45 int *tok_ptr, count;
46 int op_mask = 0;
47 char *cptr;
48 boolean should_start = false;
49
50 for(;;) {
51 (void)_setjmp(abort_environ);
52 cur.state = cmd;
53 kill_processes = false;
54 exdent(-1);
55 op_mask = 0;
56 printf("vdformat> ");
57 count = get_text_cmd(commands, tokens);
58 if(kill_processes == true)
59 _longjmp(quit_environ, 1);
60 tok_ptr = tokens;
61 if((*tok_ptr == 0) || !count)
62 continue;
63 while(*tok_ptr) {
64 switch (*tok_ptr) {
65 case RESET :
66 reset();
67 break;
68 case LIST :
69 list();
70 break;
71 case DELETE :
72 delete();
73 break;
74 case FORMAT :
75 op_mask |= FORMAT_OP;
76 break;
77 case VERIFY :
78 op_mask |= VERIFY_OP;
79 break;
80 case RELOCATE :
81 op_mask |= RELOCATE_OP;
82 break;
83 case CORRECT :
84 op_mask |= CORRECT_OP;
85 break;
86 case INFO :
87 op_mask |= INFO_OP;
88 break;
89 case PROFILE :
90 op_mask |= PROFILE_OP;
91 break;
92 case EXERCISE :
93 op_mask |= EXERCISE_OP;
94 break;
95 case START :
96 should_start = true;
97 break;
98 case EXIT:
99 exit(0);
100 /*NOTREACHED*/
101 default: /* ignore */
102 break;
103 }
104 tok_ptr++;
105 }
106 if(op_mask) {
107 get_drive_parameters(op_mask);
108 }
109 if(should_start) {
110 start_commands();
111 should_start = false;
112 }
113 }
114 }
115
116
117 /*
118 **
119 */
120
121 static boolean header_printed = false;
122
get_drive_parameters(op_mask)123 get_drive_parameters(op_mask)
124 int op_mask;
125 {
126 int c_list[20], i, num_pat;
127
128 indent();
129 header_printed = false;
130 get_ctlr_list(c_list, op_mask);
131 if(kill_processes == true) {
132 kill_processes = false;
133 c_list[0]= -1;
134 }
135 for(i=0; c_list[i] != -1; i++) {
136 int d_list[40], j;
137
138 indent();
139 get_drive_list(c_list[i], d_list, op_mask);
140 if(kill_processes == true) {
141 kill_processes = false;
142 break;
143 }
144 indent();
145 if(op_mask & (FORMAT_OP | VERIFY_OP)) {
146 num_pat = get_num_pat();
147 if(kill_processes == true) {
148 kill_processes = false;
149 break;
150 }
151 }
152 for(j=0; d_list[j] != -1; j++) {
153 cur.controller = c_list[i];
154 cur.drive = d_list[j];
155 C_INFO = &c_info[cur.controller];
156 D_INFO = &d_info[cur.controller][cur.drive];
157 lab = &D_INFO->label;
158 get_drive_type(cur.controller, cur.drive, op_mask);
159 if(kill_processes == true) {
160 kill_processes = false;
161 break;
162 }
163 if(op_mask & ~INFO_OP) {
164 indent();
165 get_drive_id(c_list[i], d_list[j]);
166 if(kill_processes == true) {
167 kill_processes = false;
168 break;
169 }
170 exdent(1);
171 }
172 ops_to_do[c_list[i]][d_list[j]].op |= op_mask;
173 if(op_mask & (FORMAT_OP | VERIFY_OP))
174 ops_to_do[c_list[i]][d_list[j]].numpat=num_pat;
175 }
176 exdent(1);
177 }
178 exdent(2);
179 }
180
181 /*
182 **
183 */
184
get_ctlr_list(c_list,op_mask)185 get_ctlr_list(c_list, op_mask)
186 int *c_list, op_mask;
187 {
188 extern int ctlr_help();
189 register int i, ctlr;
190 int table[MAXCTLR+10];
191
192 i = 0;
193 for(ctlr=0; ctlr<MAXCTLR; ctlr++)
194 if(c_info[ctlr].alive == u_true)
195 table[i++] = ctlr;
196 table[i] = -1;
197 /* If only one controller is possible don't ask */
198 if(table[1] == -1) {
199 *c_list++ = table[0];
200 *c_list = -1;
201 return;
202 }
203 for(;;) {
204 header_printed = true;
205 print(""); /* Force indent */
206 print_op_list(op_mask);
207 printf(" on which controllers? ");
208 get_digit_list(c_list, table, ctlr_help);
209 if(kill_processes == true)
210 return;
211 if(*c_list != -1)
212 break;
213 }
214 }
215
216
217 /*
218 **
219 */
220
ctlr_help()221 ctlr_help()
222 {
223 register int ctlr;
224
225 indent();
226 print("The following controllers are attached to the system:\n");
227 indent();
228 for(ctlr=0; ctlr<MAXCTLR; ctlr++)
229 if(c_info[ctlr].alive == u_true) {
230 print("Controller %d, which is a%s %s controller.\n",
231 ctlr, (c_info[ctlr].name[0] == 'S') ? "n" : "",
232 c_info[ctlr].name);
233 }
234 print("\n");
235 exdent(2);
236 }
237
238 static int max_drive = 0;
239
240 /*
241 **
242 */
243
get_drive_list(ctlr,d_list,op_mask)244 get_drive_list(ctlr, d_list, op_mask)
245 int ctlr, *d_list, op_mask;
246 {
247 extern int drive_help();
248 int table[MAXDRIVE+10];
249 int i;
250
251 max_drive = (c_info[ctlr].type == VDTYPE_VDDC) ? 4 : 16;
252 for(i=0; i<max_drive; i++)
253 table[i] = i;
254 table[i] = -1;
255 for(;;) {
256 if(header_printed == true)
257 print("Drives on controller %d? ", ctlr);
258 else {
259 header_printed = true;
260 print(""); /* Force indent */
261 print_op_list(op_mask);
262 printf(" on which drives? ");
263 }
264 get_digit_list(d_list, table, drive_help);
265 if(kill_processes == true)
266 return;
267 if(*d_list != -1)
268 break;
269 }
270 }
271
272 /*
273 **
274 */
275
id_help()276 id_help()
277 {
278 indent();
279 print("The following commands are available:\n");
280 indent();
281 print("STATus - Display formatter state.\n");
282 print("QUIT - Terminate current operation.\n");
283 print("");
284 print("A module serial can be any number greater than zero.\n");
285 exdent(2);
286 }
287
288
289 /*
290 **
291 */
292
get_drive_id(ctlr,drive)293 get_drive_id(ctlr, drive)
294 int ctlr, drive;
295 {
296 int new_id;
297
298 for(;;) {
299 print("Module serial number for controller %d, drive %d? ",
300 ctlr, drive);
301 if(d_info[ctlr][drive].id != -1)
302 printf("(%d) ", d_info[ctlr][drive].id);
303 new_id = get_digit_cmd(id_help);
304 if(new_id > 0) {
305 d_info[ctlr][drive].id = new_id;
306 break;
307 }
308 else if(d_info[ctlr][drive].id != -1)
309 break;
310 }
311 }
312
313
314 /*
315 **
316 */
317
drive_help()318 drive_help()
319 {
320 indent();
321 print("Drive numbers 0 through %d may be entered.\n", max_drive-1);
322 exdent(1);
323 }
324
325
326 /*
327 **
328 */
329
pat_help()330 pat_help()
331 {
332 indent();
333 print("Between 0 and 16 patterns may be used while verifying.\n");
334 exdent(1);
335 }
336
337
338 /*
339 **
340 */
341
get_num_pat()342 get_num_pat()
343 {
344 int table[17+10];
345 int results[17+10];
346 int i;
347
348 for(i=0; i<=16; i++)
349 table[i] = i;
350 table[i] = -1;
351 for(;;) {
352 print("Number of patterns to use while verifying? ");
353 get_digit_list(results, table, pat_help);
354 if(kill_processes == true)
355 return 0;
356 if(results[0] != -1)
357 break;
358 }
359 return results[0];
360 }
361
362