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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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