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