xref: /illumos-gate/usr/src/cmd/format/menu_cache.c (revision a2d4222865d0ef80687403e52976bd691ec2faee)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 
23 /*
24  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 /*
29  * This file contains functions that implement the cache menu commands.
30  */
31 #include "global.h"
32 #include <sys/time.h>
33 #include <sys/resource.h>
34 #include <sys/wait.h>
35 #include <signal.h>
36 #include <string.h>
37 #include <sys/fcntl.h>
38 #include <sys/stat.h>
39 
40 #include <sys/dklabel.h>
41 
42 #include "main.h"
43 #include "analyze.h"
44 #include "menu.h"
45 #include "menu_cache.h"
46 #include "param.h"
47 #include "misc.h"
48 #include "label.h"
49 #include "startup.h"
50 #include "partition.h"
51 #include "prompts.h"
52 #include "checkdev.h"
53 #include "io.h"
54 #include "ctlr_scsi.h"
55 #include "auto_sense.h"
56 #include "hardware_structs.h"
57 
58 extern	struct menu_item menu_cache[];
59 extern	struct menu_item menu_write_cache[];
60 extern	struct menu_item menu_read_cache[];
61 
62 
63 int
64 c_cache(void)
65 {
66 	cur_menu++;
67 	last_menu = cur_menu;
68 	run_menu(menu_cache, "CACHE", "cache", 0);
69 	cur_menu--;
70 	return (0);
71 }
72 
73 int
74 ca_write_cache(void)
75 {
76 	cur_menu++;
77 	last_menu = cur_menu;
78 	run_menu(menu_write_cache, "WRITE_CACHE", "write_cache", 0);
79 	cur_menu--;
80 	return (0);
81 }
82 
83 int
84 ca_read_cache(void)
85 {
86 	cur_menu++;
87 	last_menu = cur_menu;
88 	run_menu(menu_read_cache, "READ_CACHE", "read_cache", 0);
89 	cur_menu--;
90 	return (0);
91 }
92 
93 int
94 ca_write_display(void)
95 {
96 	struct mode_cache		*page8;
97 	struct scsi_ms_header		header;
98 	int				status;
99 	union {
100 		struct mode_cache	page8;
101 		char			rawbuf[MAX_MODE_SENSE_SIZE];
102 	} u_page8;
103 
104 	page8 = &u_page8.page8;
105 
106 	status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
107 	    MODE_SENSE_PC_CURRENT, (caddr_t)page8,
108 	    MAX_MODE_SENSE_SIZE, &header);
109 
110 	if (status == 0) {
111 		if (page8->wce) {
112 			fmt_print("Write Cache is enabled\n");
113 		} else {
114 			fmt_print("Write Cache is disabled\n");
115 		}
116 	} else {
117 		err_print("Mode sense failed.\n");
118 	}
119 	return (0);
120 }
121 
122 int
123 ca_write_enable(void)
124 {
125 	struct mode_cache		*page8;
126 	struct scsi_ms_header		header;
127 	int				status;
128 	int				length;
129 	int				sp_flags;
130 	union {
131 		struct mode_cache	page8;
132 		char			rawbuf[MAX_MODE_SENSE_SIZE];
133 	} u_page8;
134 
135 	page8 = &u_page8.page8;
136 
137 	status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
138 	    MODE_SENSE_PC_CHANGEABLE, (caddr_t)page8,
139 	    MAX_MODE_SENSE_SIZE, &header);
140 
141 	if (status == 0) {
142 		if (page8->wce) {
143 			status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
144 			    MODE_SENSE_PC_SAVED, (caddr_t)page8,
145 			    MAX_MODE_SENSE_SIZE, &header);
146 			if (status != 0) {
147 				status = uscsi_mode_sense(cur_file,
148 				    DAD_MODE_CACHE, MODE_SENSE_PC_CURRENT,
149 				    (caddr_t)page8, MAX_MODE_SENSE_SIZE,
150 				    &header);
151 			}
152 
153 			if (status == 0) {
154 				length = MODESENSE_PAGE_LEN(page8);
155 				sp_flags = MODE_SELECT_PF;
156 				if (page8->mode_page.ps) {
157 					sp_flags |= MODE_SELECT_SP;
158 				} else {
159 					err_print("\
160 This setting is valid until next reset only. It is not saved permanently.\n");
161 				}
162 				page8->mode_page.ps = 0;
163 				page8->wce = 1;
164 				header.mode_header.length = 0;
165 				header.mode_header.device_specific = 0;
166 				status = uscsi_mode_select(cur_file,
167 				    DAD_MODE_CACHE, sp_flags,
168 				    (caddr_t)page8, length, &header);
169 				if (status != 0) {
170 					err_print("Mode select failed\n");
171 					return (0);
172 				}
173 			}
174 		} else {
175 			err_print("Write cache setting is not changeable\n");
176 		}
177 	}
178 	if (status != 0) {
179 		err_print("Mode sense failed.\n");
180 	}
181 	return (0);
182 }
183 
184 int
185 ca_write_disable(void)
186 {
187 	struct mode_cache		*page8;
188 	struct scsi_ms_header		header;
189 	int				status;
190 	int				length;
191 	int				sp_flags;
192 	union {
193 		struct mode_cache	page8;
194 		char			rawbuf[MAX_MODE_SENSE_SIZE];
195 	} u_page8;
196 
197 	page8 = &u_page8.page8;
198 
199 	status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
200 	    MODE_SENSE_PC_CHANGEABLE, (caddr_t)page8,
201 	    MAX_MODE_SENSE_SIZE, &header);
202 
203 	if (status == 0) {
204 		if (page8->wce) {
205 			status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
206 			    MODE_SENSE_PC_SAVED, (caddr_t)page8,
207 			    MAX_MODE_SENSE_SIZE, &header);
208 			if (status != 0) {
209 				status = uscsi_mode_sense(cur_file,
210 				    DAD_MODE_CACHE, MODE_SENSE_PC_CURRENT,
211 				    (caddr_t)page8, MAX_MODE_SENSE_SIZE,
212 				    &header);
213 			}
214 
215 			if (status == 0) {
216 				length = MODESENSE_PAGE_LEN(page8);
217 				sp_flags = MODE_SELECT_PF;
218 				if (page8->mode_page.ps) {
219 					sp_flags |= MODE_SELECT_SP;
220 				} else {
221 					err_print("\
222 This setting is valid until next reset only. It is not saved permanently.\n");
223 				}
224 				page8->mode_page.ps = 0;
225 				page8->wce = 0;
226 				header.mode_header.length = 0;
227 				header.mode_header.device_specific = 0;
228 				status = uscsi_mode_select(cur_file,
229 				    DAD_MODE_CACHE, sp_flags,
230 				    (caddr_t)page8, length, &header);
231 				if (status != 0) {
232 					err_print("Mode select failed\n");
233 					return (0);
234 				}
235 			}
236 		} else {
237 			err_print("Write cache setting is not changeable\n");
238 		}
239 	}
240 	if (status != 0) {
241 		err_print("Mode sense failed.\n");
242 	}
243 	return (0);
244 }
245 
246 int
247 ca_read_display(void)
248 {
249 	struct mode_cache		*page8;
250 	struct scsi_ms_header		header;
251 	int				status;
252 	union {
253 		struct mode_cache	page8;
254 		char			rawbuf[MAX_MODE_SENSE_SIZE];
255 	} u_page8;
256 
257 	page8 = &u_page8.page8;
258 
259 	status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
260 	    MODE_SENSE_PC_CURRENT, (caddr_t)page8,
261 	    MAX_MODE_SENSE_SIZE, &header);
262 
263 	if (status == 0) {
264 		if (page8->rcd) {
265 			fmt_print("Read Cache is disabled\n");
266 		} else {
267 			fmt_print("Read Cache is enabled\n");
268 		}
269 	} else {
270 		err_print("Mode sense failed.\n");
271 	}
272 	return (0);
273 }
274 
275 int
276 ca_read_enable(void)
277 {
278 	struct mode_cache		*page8;
279 	struct scsi_ms_header		header;
280 	int				status;
281 	int				length;
282 	int				sp_flags;
283 	union {
284 		struct mode_cache	page8;
285 		char			rawbuf[MAX_MODE_SENSE_SIZE];
286 	} u_page8;
287 
288 	page8 = &u_page8.page8;
289 
290 	status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
291 	    MODE_SENSE_PC_CHANGEABLE, (caddr_t)page8,
292 	    MAX_MODE_SENSE_SIZE, &header);
293 
294 	if (status == 0) {
295 		if (page8->rcd) {
296 			status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
297 			    MODE_SENSE_PC_SAVED, (caddr_t)page8,
298 			    MAX_MODE_SENSE_SIZE, &header);
299 			if (status != 0) {
300 				status = uscsi_mode_sense(cur_file,
301 				    DAD_MODE_CACHE, MODE_SENSE_PC_CURRENT,
302 				    (caddr_t)page8, MAX_MODE_SENSE_SIZE,
303 				    &header);
304 			}
305 
306 			if (status == 0) {
307 				length = MODESENSE_PAGE_LEN(page8);
308 				sp_flags = MODE_SELECT_PF;
309 				if (page8->mode_page.ps) {
310 					sp_flags |= MODE_SELECT_SP;
311 				} else {
312 					err_print("\
313 This setting is valid until next reset only. It is not saved permanently.\n");
314 				}
315 				page8->mode_page.ps = 0;
316 				page8->rcd = 0;
317 				header.mode_header.length = 0;
318 				header.mode_header.device_specific = 0;
319 				status = uscsi_mode_select(cur_file,
320 				    DAD_MODE_CACHE, sp_flags,
321 				    (caddr_t)page8, length, &header);
322 				if (status != 0) {
323 					err_print("Mode select failed\n");
324 					return (0);
325 				}
326 			}
327 		} else {
328 			err_print("Read cache setting is not changeable\n");
329 		}
330 	}
331 	if (status != 0) {
332 		err_print("Mode sense failed.\n");
333 	}
334 	return (0);
335 }
336 
337 int
338 ca_read_disable(void)
339 {
340 	struct mode_cache		*page8;
341 	struct scsi_ms_header		header;
342 	int				status;
343 	int				length;
344 	int				sp_flags;
345 	union {
346 		struct mode_cache	page8;
347 		char			rawbuf[MAX_MODE_SENSE_SIZE];
348 	} u_page8;
349 
350 	page8 = &u_page8.page8;
351 
352 	status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
353 	    MODE_SENSE_PC_CHANGEABLE, (caddr_t)page8,
354 	    MAX_MODE_SENSE_SIZE, &header);
355 
356 	if (status == 0) {
357 		if (page8->rcd) {
358 			status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
359 			    MODE_SENSE_PC_SAVED, (caddr_t)page8,
360 			    MAX_MODE_SENSE_SIZE, &header);
361 			if (status != 0) {
362 				status = uscsi_mode_sense(cur_file,
363 				    DAD_MODE_CACHE, MODE_SENSE_PC_CURRENT,
364 				    (caddr_t)page8, MAX_MODE_SENSE_SIZE,
365 				    &header);
366 			}
367 
368 			if (status == 0) {
369 				length = MODESENSE_PAGE_LEN(page8);
370 				sp_flags = MODE_SELECT_PF;
371 				if (page8->mode_page.ps) {
372 					sp_flags |= MODE_SELECT_SP;
373 				} else {
374 					err_print("\
375 This setting is valid until next reset only. It is not saved permanently.\n");
376 				}
377 				page8->mode_page.ps = 0;
378 				page8->rcd = 1;
379 				header.mode_header.length = 0;
380 				header.mode_header.device_specific = 0;
381 				status = uscsi_mode_select(cur_file,
382 				    DAD_MODE_CACHE, sp_flags,
383 				    (caddr_t)page8, length, &header);
384 				if (status != 0) {
385 					err_print("Mode select failed\n");
386 					return (0);
387 				}
388 			}
389 		} else {
390 			err_print("Read cache setting is not changeable\n");
391 		}
392 	}
393 	if (status != 0) {
394 		err_print("Mode sense failed.\n");
395 	}
396 	return (0);
397 }
398