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 (c) 1999-2001 by Sun Microsystems, Inc. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * This file contains functions that implement the cache menu commands. 31 */ 32 #include "global.h" 33 #include <sys/time.h> 34 #include <sys/resource.h> 35 #include <sys/wait.h> 36 #include <signal.h> 37 #include <string.h> 38 #include <sys/fcntl.h> 39 #include <sys/stat.h> 40 41 #include <sys/dklabel.h> 42 43 #include "main.h" 44 #include "analyze.h" 45 #include "menu.h" 46 #include "menu_cache.h" 47 #include "param.h" 48 #include "misc.h" 49 #include "label.h" 50 #include "startup.h" 51 #include "partition.h" 52 #include "prompts.h" 53 #include "checkmount.h" 54 #include "io.h" 55 #include "ctlr_scsi.h" 56 #include "auto_sense.h" 57 #include "hardware_structs.h" 58 59 extern struct menu_item menu_cache[]; 60 extern struct menu_item menu_write_cache[]; 61 extern struct menu_item menu_read_cache[]; 62 63 64 int 65 c_cache() 66 { 67 cur_menu++; 68 last_menu = cur_menu; 69 run_menu(menu_cache, "CACHE", "cache", 0); 70 cur_menu--; 71 return (0); 72 } 73 74 int 75 ca_write_cache() 76 { 77 cur_menu++; 78 last_menu = cur_menu; 79 run_menu(menu_write_cache, "WRITE_CACHE", "write_cache", 0); 80 cur_menu--; 81 return (0); 82 } 83 84 int 85 ca_read_cache() 86 { 87 cur_menu++; 88 last_menu = cur_menu; 89 run_menu(menu_read_cache, "READ_CACHE", "read_cache", 0); 90 cur_menu--; 91 return (0); 92 } 93 94 int 95 ca_write_display() 96 { 97 struct mode_cache *page8; 98 struct scsi_ms_header header; 99 int status; 100 union { 101 struct mode_cache page8; 102 char rawbuf[MAX_MODE_SENSE_SIZE]; 103 } u_page8; 104 105 page8 = &u_page8.page8; 106 107 status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE, 108 MODE_SENSE_PC_CURRENT, (caddr_t)page8, 109 MAX_MODE_SENSE_SIZE, &header); 110 111 if (status == 0) { 112 if (page8->wce) { 113 fmt_print("Write Cache is enabled\n"); 114 } else { 115 fmt_print("Write Cache is disabled\n"); 116 } 117 } else { 118 err_print("Mode sense failed.\n"); 119 } 120 return (0); 121 } 122 123 int 124 ca_write_enable() 125 { 126 struct mode_cache *page8; 127 struct scsi_ms_header header; 128 int status; 129 int length; 130 int sp_flags; 131 union { 132 struct mode_cache page8; 133 char rawbuf[MAX_MODE_SENSE_SIZE]; 134 } u_page8; 135 136 page8 = &u_page8.page8; 137 138 status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE, 139 MODE_SENSE_PC_CHANGEABLE, (caddr_t)page8, 140 MAX_MODE_SENSE_SIZE, &header); 141 142 if (status == 0) { 143 if (page8->wce) { 144 status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE, 145 MODE_SENSE_PC_SAVED, (caddr_t)page8, 146 MAX_MODE_SENSE_SIZE, &header); 147 if (status != 0) { 148 status = uscsi_mode_sense(cur_file, 149 DAD_MODE_CACHE, MODE_SENSE_PC_CURRENT, 150 (caddr_t)page8, MAX_MODE_SENSE_SIZE, &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() 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, &header); 212 } 213 214 if (status == 0) { 215 length = MODESENSE_PAGE_LEN(page8); 216 sp_flags = MODE_SELECT_PF; 217 if (page8->mode_page.ps) { 218 sp_flags |= MODE_SELECT_SP; 219 } else { 220 err_print("\ 221 This setting is valid until next reset only. It is not saved permanently.\n"); 222 } 223 page8->mode_page.ps = 0; 224 page8->wce = 0; 225 header.mode_header.length = 0; 226 header.mode_header.device_specific = 0; 227 status = uscsi_mode_select(cur_file, 228 DAD_MODE_CACHE, sp_flags, 229 (caddr_t)page8, length, &header); 230 if (status != 0) { 231 err_print("Mode select failed\n"); 232 return (0); 233 } 234 } 235 } else { 236 err_print("Write cache setting is not changeable\n"); 237 } 238 } 239 if (status != 0) { 240 err_print("Mode sense failed.\n"); 241 } 242 return (0); 243 } 244 245 int 246 ca_read_display() 247 { 248 struct mode_cache *page8; 249 struct scsi_ms_header header; 250 int status; 251 union { 252 struct mode_cache page8; 253 char rawbuf[MAX_MODE_SENSE_SIZE]; 254 } u_page8; 255 256 page8 = &u_page8.page8; 257 258 status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE, 259 MODE_SENSE_PC_CURRENT, (caddr_t)page8, 260 MAX_MODE_SENSE_SIZE, &header); 261 262 if (status == 0) { 263 if (page8->rcd) { 264 fmt_print("Read Cache is disabled\n"); 265 } else { 266 fmt_print("Read Cache is enabled\n"); 267 } 268 } else { 269 err_print("Mode sense failed.\n"); 270 } 271 return (0); 272 } 273 274 int 275 ca_read_enable() 276 { 277 struct mode_cache *page8; 278 struct scsi_ms_header header; 279 int status; 280 int length; 281 int sp_flags; 282 union { 283 struct mode_cache page8; 284 char rawbuf[MAX_MODE_SENSE_SIZE]; 285 } u_page8; 286 287 page8 = &u_page8.page8; 288 289 status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE, 290 MODE_SENSE_PC_CHANGEABLE, (caddr_t)page8, 291 MAX_MODE_SENSE_SIZE, &header); 292 293 if (status == 0) { 294 if (page8->rcd) { 295 status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE, 296 MODE_SENSE_PC_SAVED, (caddr_t)page8, 297 MAX_MODE_SENSE_SIZE, &header); 298 if (status != 0) { 299 status = uscsi_mode_sense(cur_file, 300 DAD_MODE_CACHE, MODE_SENSE_PC_CURRENT, 301 (caddr_t)page8, MAX_MODE_SENSE_SIZE, &header); 302 } 303 304 if (status == 0) { 305 length = MODESENSE_PAGE_LEN(page8); 306 sp_flags = MODE_SELECT_PF; 307 if (page8->mode_page.ps) { 308 sp_flags |= MODE_SELECT_SP; 309 } else { 310 err_print("\ 311 This setting is valid until next reset only. It is not saved permanently.\n"); 312 } 313 page8->mode_page.ps = 0; 314 page8->rcd = 0; 315 header.mode_header.length = 0; 316 header.mode_header.device_specific = 0; 317 status = uscsi_mode_select(cur_file, 318 DAD_MODE_CACHE, sp_flags, 319 (caddr_t)page8, length, &header); 320 if (status != 0) { 321 err_print("Mode select failed\n"); 322 return (0); 323 } 324 } 325 } else { 326 err_print("Read cache setting is not changeable\n"); 327 } 328 } 329 if (status != 0) { 330 err_print("Mode sense failed.\n"); 331 } 332 return (0); 333 } 334 335 int 336 ca_read_disable() 337 { 338 struct mode_cache *page8; 339 struct scsi_ms_header header; 340 int status; 341 int length; 342 int sp_flags; 343 union { 344 struct mode_cache page8; 345 char rawbuf[MAX_MODE_SENSE_SIZE]; 346 } u_page8; 347 348 page8 = &u_page8.page8; 349 350 status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE, 351 MODE_SENSE_PC_CHANGEABLE, (caddr_t)page8, 352 MAX_MODE_SENSE_SIZE, &header); 353 354 if (status == 0) { 355 if (page8->rcd) { 356 status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE, 357 MODE_SENSE_PC_SAVED, (caddr_t)page8, 358 MAX_MODE_SENSE_SIZE, &header); 359 if (status != 0) { 360 status = uscsi_mode_sense(cur_file, 361 DAD_MODE_CACHE, MODE_SENSE_PC_CURRENT, 362 (caddr_t)page8, MAX_MODE_SENSE_SIZE, &header); 363 } 364 365 if (status == 0) { 366 length = MODESENSE_PAGE_LEN(page8); 367 sp_flags = MODE_SELECT_PF; 368 if (page8->mode_page.ps) { 369 sp_flags |= MODE_SELECT_SP; 370 } else { 371 err_print("\ 372 This setting is valid until next reset only. It is not saved permanently.\n"); 373 } 374 page8->mode_page.ps = 0; 375 page8->rcd = 1; 376 header.mode_header.length = 0; 377 header.mode_header.device_specific = 0; 378 status = uscsi_mode_select(cur_file, 379 DAD_MODE_CACHE, sp_flags, 380 (caddr_t)page8, length, &header); 381 if (status != 0) { 382 err_print("Mode select failed\n"); 383 return (0); 384 } 385 } 386 } else { 387 err_print("Read cache setting is not changeable\n"); 388 } 389 } 390 if (status != 0) { 391 err_print("Mode sense failed.\n"); 392 } 393 return (0); 394 } 395