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
c_cache(void)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
ca_write_cache(void)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
ca_read_cache(void)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
ca_write_display(void)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
ca_write_enable(void)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
ca_write_disable(void)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
ca_read_display(void)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
ca_read_enable(void)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
ca_read_disable(void)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