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