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 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 /* 31 * This file contains functions that implement the cache menu commands. 32 */ 33 #include "global.h" 34 #include <sys/time.h> 35 #include <sys/resource.h> 36 #include <sys/wait.h> 37 #include <signal.h> 38 #include <string.h> 39 #include <sys/fcntl.h> 40 #include <sys/stat.h> 41 42 #include <sys/dklabel.h> 43 44 #include "main.h" 45 #include "analyze.h" 46 #include "menu.h" 47 #include "menu_cache.h" 48 #include "param.h" 49 #include "misc.h" 50 #include "label.h" 51 #include "startup.h" 52 #include "partition.h" 53 #include "prompts.h" 54 #include "checkdev.h" 55 #include "io.h" 56 #include "ctlr_scsi.h" 57 #include "auto_sense.h" 58 #include "hardware_structs.h" 59 60 extern struct menu_item menu_cache[]; 61 extern struct menu_item menu_write_cache[]; 62 extern struct menu_item menu_read_cache[]; 63 64 65 int 66 c_cache() 67 { 68 cur_menu++; 69 last_menu = cur_menu; 70 run_menu(menu_cache, "CACHE", "cache", 0); 71 cur_menu--; 72 return (0); 73 } 74 75 int 76 ca_write_cache() 77 { 78 cur_menu++; 79 last_menu = cur_menu; 80 run_menu(menu_write_cache, "WRITE_CACHE", "write_cache", 0); 81 cur_menu--; 82 return (0); 83 } 84 85 int 86 ca_read_cache() 87 { 88 cur_menu++; 89 last_menu = cur_menu; 90 run_menu(menu_read_cache, "READ_CACHE", "read_cache", 0); 91 cur_menu--; 92 return (0); 93 } 94 95 int 96 ca_write_display() 97 { 98 struct mode_cache *page8; 99 struct scsi_ms_header header; 100 int status; 101 union { 102 struct mode_cache page8; 103 char rawbuf[MAX_MODE_SENSE_SIZE]; 104 } u_page8; 105 106 page8 = &u_page8.page8; 107 108 status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE, 109 MODE_SENSE_PC_CURRENT, (caddr_t)page8, 110 MAX_MODE_SENSE_SIZE, &header); 111 112 if (status == 0) { 113 if (page8->wce) { 114 fmt_print("Write Cache is enabled\n"); 115 } else { 116 fmt_print("Write Cache is disabled\n"); 117 } 118 } else { 119 err_print("Mode sense failed.\n"); 120 } 121 return (0); 122 } 123 124 int 125 ca_write_enable() 126 { 127 struct mode_cache *page8; 128 struct scsi_ms_header header; 129 int status; 130 int length; 131 int sp_flags; 132 union { 133 struct mode_cache page8; 134 char rawbuf[MAX_MODE_SENSE_SIZE]; 135 } u_page8; 136 137 page8 = &u_page8.page8; 138 139 status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE, 140 MODE_SENSE_PC_CHANGEABLE, (caddr_t)page8, 141 MAX_MODE_SENSE_SIZE, &header); 142 143 if (status == 0) { 144 if (page8->wce) { 145 status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE, 146 MODE_SENSE_PC_SAVED, (caddr_t)page8, 147 MAX_MODE_SENSE_SIZE, &header); 148 if (status != 0) { 149 status = uscsi_mode_sense(cur_file, 150 DAD_MODE_CACHE, MODE_SENSE_PC_CURRENT, 151 (caddr_t)page8, MAX_MODE_SENSE_SIZE, &header); 152 } 153 154 if (status == 0) { 155 length = MODESENSE_PAGE_LEN(page8); 156 sp_flags = MODE_SELECT_PF; 157 if (page8->mode_page.ps) { 158 sp_flags |= MODE_SELECT_SP; 159 } else { 160 err_print("\ 161 This setting is valid until next reset only. It is not saved permanently.\n"); 162 } 163 page8->mode_page.ps = 0; 164 page8->wce = 1; 165 header.mode_header.length = 0; 166 header.mode_header.device_specific = 0; 167 status = uscsi_mode_select(cur_file, 168 DAD_MODE_CACHE, sp_flags, 169 (caddr_t)page8, length, &header); 170 if (status != 0) { 171 err_print("Mode select failed\n"); 172 return (0); 173 } 174 } 175 } else { 176 err_print("Write cache setting is not changeable\n"); 177 } 178 } 179 if (status != 0) { 180 err_print("Mode sense failed.\n"); 181 } 182 return (0); 183 } 184 185 int 186 ca_write_disable() 187 { 188 struct mode_cache *page8; 189 struct scsi_ms_header header; 190 int status; 191 int length; 192 int sp_flags; 193 union { 194 struct mode_cache page8; 195 char rawbuf[MAX_MODE_SENSE_SIZE]; 196 } u_page8; 197 198 page8 = &u_page8.page8; 199 200 status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE, 201 MODE_SENSE_PC_CHANGEABLE, (caddr_t)page8, 202 MAX_MODE_SENSE_SIZE, &header); 203 204 if (status == 0) { 205 if (page8->wce) { 206 status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE, 207 MODE_SENSE_PC_SAVED, (caddr_t)page8, 208 MAX_MODE_SENSE_SIZE, &header); 209 if (status != 0) { 210 status = uscsi_mode_sense(cur_file, 211 DAD_MODE_CACHE, MODE_SENSE_PC_CURRENT, 212 (caddr_t)page8, MAX_MODE_SENSE_SIZE, &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() 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() 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, &header); 303 } 304 305 if (status == 0) { 306 length = MODESENSE_PAGE_LEN(page8); 307 sp_flags = MODE_SELECT_PF; 308 if (page8->mode_page.ps) { 309 sp_flags |= MODE_SELECT_SP; 310 } else { 311 err_print("\ 312 This setting is valid until next reset only. It is not saved permanently.\n"); 313 } 314 page8->mode_page.ps = 0; 315 page8->rcd = 0; 316 header.mode_header.length = 0; 317 header.mode_header.device_specific = 0; 318 status = uscsi_mode_select(cur_file, 319 DAD_MODE_CACHE, sp_flags, 320 (caddr_t)page8, length, &header); 321 if (status != 0) { 322 err_print("Mode select failed\n"); 323 return (0); 324 } 325 } 326 } else { 327 err_print("Read cache setting is not changeable\n"); 328 } 329 } 330 if (status != 0) { 331 err_print("Mode sense failed.\n"); 332 } 333 return (0); 334 } 335 336 int 337 ca_read_disable() 338 { 339 struct mode_cache *page8; 340 struct scsi_ms_header header; 341 int status; 342 int length; 343 int sp_flags; 344 union { 345 struct mode_cache page8; 346 char rawbuf[MAX_MODE_SENSE_SIZE]; 347 } u_page8; 348 349 page8 = &u_page8.page8; 350 351 status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE, 352 MODE_SENSE_PC_CHANGEABLE, (caddr_t)page8, 353 MAX_MODE_SENSE_SIZE, &header); 354 355 if (status == 0) { 356 if (page8->rcd) { 357 status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE, 358 MODE_SENSE_PC_SAVED, (caddr_t)page8, 359 MAX_MODE_SENSE_SIZE, &header); 360 if (status != 0) { 361 status = uscsi_mode_sense(cur_file, 362 DAD_MODE_CACHE, MODE_SENSE_PC_CURRENT, 363 (caddr_t)page8, MAX_MODE_SENSE_SIZE, &header); 364 } 365 366 if (status == 0) { 367 length = MODESENSE_PAGE_LEN(page8); 368 sp_flags = MODE_SELECT_PF; 369 if (page8->mode_page.ps) { 370 sp_flags |= MODE_SELECT_SP; 371 } else { 372 err_print("\ 373 This setting is valid until next reset only. It is not saved permanently.\n"); 374 } 375 page8->mode_page.ps = 0; 376 page8->rcd = 1; 377 header.mode_header.length = 0; 378 header.mode_header.device_specific = 0; 379 status = uscsi_mode_select(cur_file, 380 DAD_MODE_CACHE, sp_flags, 381 (caddr_t)page8, length, &header); 382 if (status != 0) { 383 err_print("Mode select failed\n"); 384 return (0); 385 } 386 } 387 } else { 388 err_print("Read cache setting is not changeable\n"); 389 } 390 } 391 if (status != 0) { 392 err_print("Mode sense failed.\n"); 393 } 394 return (0); 395 } 396