10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
70Sstevel@tonic-gate * with the License.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate * See the License for the specific language governing permissions
120Sstevel@tonic-gate * and limitations under the License.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * CDDL HEADER END
210Sstevel@tonic-gate */
220Sstevel@tonic-gate
230Sstevel@tonic-gate /*
24*767Ssjelinek * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
25*767Ssjelinek * Use is subject to license terms.
260Sstevel@tonic-gate */
270Sstevel@tonic-gate
280Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
290Sstevel@tonic-gate
300Sstevel@tonic-gate /*
310Sstevel@tonic-gate * This file contains functions that implement the cache menu commands.
320Sstevel@tonic-gate */
330Sstevel@tonic-gate #include "global.h"
340Sstevel@tonic-gate #include <sys/time.h>
350Sstevel@tonic-gate #include <sys/resource.h>
360Sstevel@tonic-gate #include <sys/wait.h>
370Sstevel@tonic-gate #include <signal.h>
380Sstevel@tonic-gate #include <string.h>
390Sstevel@tonic-gate #include <sys/fcntl.h>
400Sstevel@tonic-gate #include <sys/stat.h>
410Sstevel@tonic-gate
420Sstevel@tonic-gate #include <sys/dklabel.h>
430Sstevel@tonic-gate
440Sstevel@tonic-gate #include "main.h"
450Sstevel@tonic-gate #include "analyze.h"
460Sstevel@tonic-gate #include "menu.h"
470Sstevel@tonic-gate #include "menu_cache.h"
480Sstevel@tonic-gate #include "param.h"
490Sstevel@tonic-gate #include "misc.h"
500Sstevel@tonic-gate #include "label.h"
510Sstevel@tonic-gate #include "startup.h"
520Sstevel@tonic-gate #include "partition.h"
530Sstevel@tonic-gate #include "prompts.h"
54*767Ssjelinek #include "checkdev.h"
550Sstevel@tonic-gate #include "io.h"
560Sstevel@tonic-gate #include "ctlr_scsi.h"
570Sstevel@tonic-gate #include "auto_sense.h"
580Sstevel@tonic-gate #include "hardware_structs.h"
590Sstevel@tonic-gate
600Sstevel@tonic-gate extern struct menu_item menu_cache[];
610Sstevel@tonic-gate extern struct menu_item menu_write_cache[];
620Sstevel@tonic-gate extern struct menu_item menu_read_cache[];
630Sstevel@tonic-gate
640Sstevel@tonic-gate
650Sstevel@tonic-gate int
c_cache()660Sstevel@tonic-gate c_cache()
670Sstevel@tonic-gate {
680Sstevel@tonic-gate cur_menu++;
690Sstevel@tonic-gate last_menu = cur_menu;
700Sstevel@tonic-gate run_menu(menu_cache, "CACHE", "cache", 0);
710Sstevel@tonic-gate cur_menu--;
720Sstevel@tonic-gate return (0);
730Sstevel@tonic-gate }
740Sstevel@tonic-gate
750Sstevel@tonic-gate int
ca_write_cache()760Sstevel@tonic-gate ca_write_cache()
770Sstevel@tonic-gate {
780Sstevel@tonic-gate cur_menu++;
790Sstevel@tonic-gate last_menu = cur_menu;
800Sstevel@tonic-gate run_menu(menu_write_cache, "WRITE_CACHE", "write_cache", 0);
810Sstevel@tonic-gate cur_menu--;
820Sstevel@tonic-gate return (0);
830Sstevel@tonic-gate }
840Sstevel@tonic-gate
850Sstevel@tonic-gate int
ca_read_cache()860Sstevel@tonic-gate ca_read_cache()
870Sstevel@tonic-gate {
880Sstevel@tonic-gate cur_menu++;
890Sstevel@tonic-gate last_menu = cur_menu;
900Sstevel@tonic-gate run_menu(menu_read_cache, "READ_CACHE", "read_cache", 0);
910Sstevel@tonic-gate cur_menu--;
920Sstevel@tonic-gate return (0);
930Sstevel@tonic-gate }
940Sstevel@tonic-gate
950Sstevel@tonic-gate int
ca_write_display()960Sstevel@tonic-gate ca_write_display()
970Sstevel@tonic-gate {
980Sstevel@tonic-gate struct mode_cache *page8;
990Sstevel@tonic-gate struct scsi_ms_header header;
1000Sstevel@tonic-gate int status;
1010Sstevel@tonic-gate union {
1020Sstevel@tonic-gate struct mode_cache page8;
1030Sstevel@tonic-gate char rawbuf[MAX_MODE_SENSE_SIZE];
1040Sstevel@tonic-gate } u_page8;
1050Sstevel@tonic-gate
1060Sstevel@tonic-gate page8 = &u_page8.page8;
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
1090Sstevel@tonic-gate MODE_SENSE_PC_CURRENT, (caddr_t)page8,
1100Sstevel@tonic-gate MAX_MODE_SENSE_SIZE, &header);
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate if (status == 0) {
1130Sstevel@tonic-gate if (page8->wce) {
1140Sstevel@tonic-gate fmt_print("Write Cache is enabled\n");
1150Sstevel@tonic-gate } else {
1160Sstevel@tonic-gate fmt_print("Write Cache is disabled\n");
1170Sstevel@tonic-gate }
1180Sstevel@tonic-gate } else {
1190Sstevel@tonic-gate err_print("Mode sense failed.\n");
1200Sstevel@tonic-gate }
1210Sstevel@tonic-gate return (0);
1220Sstevel@tonic-gate }
1230Sstevel@tonic-gate
1240Sstevel@tonic-gate int
ca_write_enable()1250Sstevel@tonic-gate ca_write_enable()
1260Sstevel@tonic-gate {
1270Sstevel@tonic-gate struct mode_cache *page8;
1280Sstevel@tonic-gate struct scsi_ms_header header;
1290Sstevel@tonic-gate int status;
1300Sstevel@tonic-gate int length;
1310Sstevel@tonic-gate int sp_flags;
1320Sstevel@tonic-gate union {
1330Sstevel@tonic-gate struct mode_cache page8;
1340Sstevel@tonic-gate char rawbuf[MAX_MODE_SENSE_SIZE];
1350Sstevel@tonic-gate } u_page8;
1360Sstevel@tonic-gate
1370Sstevel@tonic-gate page8 = &u_page8.page8;
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
1400Sstevel@tonic-gate MODE_SENSE_PC_CHANGEABLE, (caddr_t)page8,
1410Sstevel@tonic-gate MAX_MODE_SENSE_SIZE, &header);
1420Sstevel@tonic-gate
1430Sstevel@tonic-gate if (status == 0) {
1440Sstevel@tonic-gate if (page8->wce) {
1450Sstevel@tonic-gate status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
1460Sstevel@tonic-gate MODE_SENSE_PC_SAVED, (caddr_t)page8,
1470Sstevel@tonic-gate MAX_MODE_SENSE_SIZE, &header);
1480Sstevel@tonic-gate if (status != 0) {
1490Sstevel@tonic-gate status = uscsi_mode_sense(cur_file,
1500Sstevel@tonic-gate DAD_MODE_CACHE, MODE_SENSE_PC_CURRENT,
1510Sstevel@tonic-gate (caddr_t)page8, MAX_MODE_SENSE_SIZE, &header);
1520Sstevel@tonic-gate }
1530Sstevel@tonic-gate
1540Sstevel@tonic-gate if (status == 0) {
1550Sstevel@tonic-gate length = MODESENSE_PAGE_LEN(page8);
1560Sstevel@tonic-gate sp_flags = MODE_SELECT_PF;
1570Sstevel@tonic-gate if (page8->mode_page.ps) {
1580Sstevel@tonic-gate sp_flags |= MODE_SELECT_SP;
1590Sstevel@tonic-gate } else {
1600Sstevel@tonic-gate err_print("\
1610Sstevel@tonic-gate This setting is valid until next reset only. It is not saved permanently.\n");
1620Sstevel@tonic-gate }
1630Sstevel@tonic-gate page8->mode_page.ps = 0;
1640Sstevel@tonic-gate page8->wce = 1;
1650Sstevel@tonic-gate header.mode_header.length = 0;
1660Sstevel@tonic-gate header.mode_header.device_specific = 0;
1670Sstevel@tonic-gate status = uscsi_mode_select(cur_file,
1680Sstevel@tonic-gate DAD_MODE_CACHE, sp_flags,
1690Sstevel@tonic-gate (caddr_t)page8, length, &header);
1700Sstevel@tonic-gate if (status != 0) {
1710Sstevel@tonic-gate err_print("Mode select failed\n");
1720Sstevel@tonic-gate return (0);
1730Sstevel@tonic-gate }
1740Sstevel@tonic-gate }
1750Sstevel@tonic-gate } else {
1760Sstevel@tonic-gate err_print("Write cache setting is not changeable\n");
1770Sstevel@tonic-gate }
1780Sstevel@tonic-gate }
1790Sstevel@tonic-gate if (status != 0) {
1800Sstevel@tonic-gate err_print("Mode sense failed.\n");
1810Sstevel@tonic-gate }
1820Sstevel@tonic-gate return (0);
1830Sstevel@tonic-gate }
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate int
ca_write_disable()1860Sstevel@tonic-gate ca_write_disable()
1870Sstevel@tonic-gate {
1880Sstevel@tonic-gate struct mode_cache *page8;
1890Sstevel@tonic-gate struct scsi_ms_header header;
1900Sstevel@tonic-gate int status;
1910Sstevel@tonic-gate int length;
1920Sstevel@tonic-gate int sp_flags;
1930Sstevel@tonic-gate union {
1940Sstevel@tonic-gate struct mode_cache page8;
1950Sstevel@tonic-gate char rawbuf[MAX_MODE_SENSE_SIZE];
1960Sstevel@tonic-gate } u_page8;
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate page8 = &u_page8.page8;
1990Sstevel@tonic-gate
2000Sstevel@tonic-gate status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
2010Sstevel@tonic-gate MODE_SENSE_PC_CHANGEABLE, (caddr_t)page8,
2020Sstevel@tonic-gate MAX_MODE_SENSE_SIZE, &header);
2030Sstevel@tonic-gate
2040Sstevel@tonic-gate if (status == 0) {
2050Sstevel@tonic-gate if (page8->wce) {
2060Sstevel@tonic-gate status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
2070Sstevel@tonic-gate MODE_SENSE_PC_SAVED, (caddr_t)page8,
2080Sstevel@tonic-gate MAX_MODE_SENSE_SIZE, &header);
2090Sstevel@tonic-gate if (status != 0) {
2100Sstevel@tonic-gate status = uscsi_mode_sense(cur_file,
2110Sstevel@tonic-gate DAD_MODE_CACHE, MODE_SENSE_PC_CURRENT,
2120Sstevel@tonic-gate (caddr_t)page8, MAX_MODE_SENSE_SIZE, &header);
2130Sstevel@tonic-gate }
2140Sstevel@tonic-gate
2150Sstevel@tonic-gate if (status == 0) {
2160Sstevel@tonic-gate length = MODESENSE_PAGE_LEN(page8);
2170Sstevel@tonic-gate sp_flags = MODE_SELECT_PF;
2180Sstevel@tonic-gate if (page8->mode_page.ps) {
2190Sstevel@tonic-gate sp_flags |= MODE_SELECT_SP;
2200Sstevel@tonic-gate } else {
2210Sstevel@tonic-gate err_print("\
2220Sstevel@tonic-gate This setting is valid until next reset only. It is not saved permanently.\n");
2230Sstevel@tonic-gate }
2240Sstevel@tonic-gate page8->mode_page.ps = 0;
2250Sstevel@tonic-gate page8->wce = 0;
2260Sstevel@tonic-gate header.mode_header.length = 0;
2270Sstevel@tonic-gate header.mode_header.device_specific = 0;
2280Sstevel@tonic-gate status = uscsi_mode_select(cur_file,
2290Sstevel@tonic-gate DAD_MODE_CACHE, sp_flags,
2300Sstevel@tonic-gate (caddr_t)page8, length, &header);
2310Sstevel@tonic-gate if (status != 0) {
2320Sstevel@tonic-gate err_print("Mode select failed\n");
2330Sstevel@tonic-gate return (0);
2340Sstevel@tonic-gate }
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate } else {
2370Sstevel@tonic-gate err_print("Write cache setting is not changeable\n");
2380Sstevel@tonic-gate }
2390Sstevel@tonic-gate }
2400Sstevel@tonic-gate if (status != 0) {
2410Sstevel@tonic-gate err_print("Mode sense failed.\n");
2420Sstevel@tonic-gate }
2430Sstevel@tonic-gate return (0);
2440Sstevel@tonic-gate }
2450Sstevel@tonic-gate
2460Sstevel@tonic-gate int
ca_read_display()2470Sstevel@tonic-gate ca_read_display()
2480Sstevel@tonic-gate {
2490Sstevel@tonic-gate struct mode_cache *page8;
2500Sstevel@tonic-gate struct scsi_ms_header header;
2510Sstevel@tonic-gate int status;
2520Sstevel@tonic-gate union {
2530Sstevel@tonic-gate struct mode_cache page8;
2540Sstevel@tonic-gate char rawbuf[MAX_MODE_SENSE_SIZE];
2550Sstevel@tonic-gate } u_page8;
2560Sstevel@tonic-gate
2570Sstevel@tonic-gate page8 = &u_page8.page8;
2580Sstevel@tonic-gate
2590Sstevel@tonic-gate status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
2600Sstevel@tonic-gate MODE_SENSE_PC_CURRENT, (caddr_t)page8,
2610Sstevel@tonic-gate MAX_MODE_SENSE_SIZE, &header);
2620Sstevel@tonic-gate
2630Sstevel@tonic-gate if (status == 0) {
2640Sstevel@tonic-gate if (page8->rcd) {
2650Sstevel@tonic-gate fmt_print("Read Cache is disabled\n");
2660Sstevel@tonic-gate } else {
2670Sstevel@tonic-gate fmt_print("Read Cache is enabled\n");
2680Sstevel@tonic-gate }
2690Sstevel@tonic-gate } else {
2700Sstevel@tonic-gate err_print("Mode sense failed.\n");
2710Sstevel@tonic-gate }
2720Sstevel@tonic-gate return (0);
2730Sstevel@tonic-gate }
2740Sstevel@tonic-gate
2750Sstevel@tonic-gate int
ca_read_enable()2760Sstevel@tonic-gate ca_read_enable()
2770Sstevel@tonic-gate {
2780Sstevel@tonic-gate struct mode_cache *page8;
2790Sstevel@tonic-gate struct scsi_ms_header header;
2800Sstevel@tonic-gate int status;
2810Sstevel@tonic-gate int length;
2820Sstevel@tonic-gate int sp_flags;
2830Sstevel@tonic-gate union {
2840Sstevel@tonic-gate struct mode_cache page8;
2850Sstevel@tonic-gate char rawbuf[MAX_MODE_SENSE_SIZE];
2860Sstevel@tonic-gate } u_page8;
2870Sstevel@tonic-gate
2880Sstevel@tonic-gate page8 = &u_page8.page8;
2890Sstevel@tonic-gate
2900Sstevel@tonic-gate status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
2910Sstevel@tonic-gate MODE_SENSE_PC_CHANGEABLE, (caddr_t)page8,
2920Sstevel@tonic-gate MAX_MODE_SENSE_SIZE, &header);
2930Sstevel@tonic-gate
2940Sstevel@tonic-gate if (status == 0) {
2950Sstevel@tonic-gate if (page8->rcd) {
2960Sstevel@tonic-gate status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
2970Sstevel@tonic-gate MODE_SENSE_PC_SAVED, (caddr_t)page8,
2980Sstevel@tonic-gate MAX_MODE_SENSE_SIZE, &header);
2990Sstevel@tonic-gate if (status != 0) {
3000Sstevel@tonic-gate status = uscsi_mode_sense(cur_file,
3010Sstevel@tonic-gate DAD_MODE_CACHE, MODE_SENSE_PC_CURRENT,
3020Sstevel@tonic-gate (caddr_t)page8, MAX_MODE_SENSE_SIZE, &header);
3030Sstevel@tonic-gate }
3040Sstevel@tonic-gate
3050Sstevel@tonic-gate if (status == 0) {
3060Sstevel@tonic-gate length = MODESENSE_PAGE_LEN(page8);
3070Sstevel@tonic-gate sp_flags = MODE_SELECT_PF;
3080Sstevel@tonic-gate if (page8->mode_page.ps) {
3090Sstevel@tonic-gate sp_flags |= MODE_SELECT_SP;
3100Sstevel@tonic-gate } else {
3110Sstevel@tonic-gate err_print("\
3120Sstevel@tonic-gate This setting is valid until next reset only. It is not saved permanently.\n");
3130Sstevel@tonic-gate }
3140Sstevel@tonic-gate page8->mode_page.ps = 0;
3150Sstevel@tonic-gate page8->rcd = 0;
3160Sstevel@tonic-gate header.mode_header.length = 0;
3170Sstevel@tonic-gate header.mode_header.device_specific = 0;
3180Sstevel@tonic-gate status = uscsi_mode_select(cur_file,
3190Sstevel@tonic-gate DAD_MODE_CACHE, sp_flags,
3200Sstevel@tonic-gate (caddr_t)page8, length, &header);
3210Sstevel@tonic-gate if (status != 0) {
3220Sstevel@tonic-gate err_print("Mode select failed\n");
3230Sstevel@tonic-gate return (0);
3240Sstevel@tonic-gate }
3250Sstevel@tonic-gate }
3260Sstevel@tonic-gate } else {
3270Sstevel@tonic-gate err_print("Read cache setting is not changeable\n");
3280Sstevel@tonic-gate }
3290Sstevel@tonic-gate }
3300Sstevel@tonic-gate if (status != 0) {
3310Sstevel@tonic-gate err_print("Mode sense failed.\n");
3320Sstevel@tonic-gate }
3330Sstevel@tonic-gate return (0);
3340Sstevel@tonic-gate }
3350Sstevel@tonic-gate
3360Sstevel@tonic-gate int
ca_read_disable()3370Sstevel@tonic-gate ca_read_disable()
3380Sstevel@tonic-gate {
3390Sstevel@tonic-gate struct mode_cache *page8;
3400Sstevel@tonic-gate struct scsi_ms_header header;
3410Sstevel@tonic-gate int status;
3420Sstevel@tonic-gate int length;
3430Sstevel@tonic-gate int sp_flags;
3440Sstevel@tonic-gate union {
3450Sstevel@tonic-gate struct mode_cache page8;
3460Sstevel@tonic-gate char rawbuf[MAX_MODE_SENSE_SIZE];
3470Sstevel@tonic-gate } u_page8;
3480Sstevel@tonic-gate
3490Sstevel@tonic-gate page8 = &u_page8.page8;
3500Sstevel@tonic-gate
3510Sstevel@tonic-gate status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
3520Sstevel@tonic-gate MODE_SENSE_PC_CHANGEABLE, (caddr_t)page8,
3530Sstevel@tonic-gate MAX_MODE_SENSE_SIZE, &header);
3540Sstevel@tonic-gate
3550Sstevel@tonic-gate if (status == 0) {
3560Sstevel@tonic-gate if (page8->rcd) {
3570Sstevel@tonic-gate status = uscsi_mode_sense(cur_file, DAD_MODE_CACHE,
3580Sstevel@tonic-gate MODE_SENSE_PC_SAVED, (caddr_t)page8,
3590Sstevel@tonic-gate MAX_MODE_SENSE_SIZE, &header);
3600Sstevel@tonic-gate if (status != 0) {
3610Sstevel@tonic-gate status = uscsi_mode_sense(cur_file,
3620Sstevel@tonic-gate DAD_MODE_CACHE, MODE_SENSE_PC_CURRENT,
3630Sstevel@tonic-gate (caddr_t)page8, MAX_MODE_SENSE_SIZE, &header);
3640Sstevel@tonic-gate }
3650Sstevel@tonic-gate
3660Sstevel@tonic-gate if (status == 0) {
3670Sstevel@tonic-gate length = MODESENSE_PAGE_LEN(page8);
3680Sstevel@tonic-gate sp_flags = MODE_SELECT_PF;
3690Sstevel@tonic-gate if (page8->mode_page.ps) {
3700Sstevel@tonic-gate sp_flags |= MODE_SELECT_SP;
3710Sstevel@tonic-gate } else {
3720Sstevel@tonic-gate err_print("\
3730Sstevel@tonic-gate This setting is valid until next reset only. It is not saved permanently.\n");
3740Sstevel@tonic-gate }
3750Sstevel@tonic-gate page8->mode_page.ps = 0;
3760Sstevel@tonic-gate page8->rcd = 1;
3770Sstevel@tonic-gate header.mode_header.length = 0;
3780Sstevel@tonic-gate header.mode_header.device_specific = 0;
3790Sstevel@tonic-gate status = uscsi_mode_select(cur_file,
3800Sstevel@tonic-gate DAD_MODE_CACHE, sp_flags,
3810Sstevel@tonic-gate (caddr_t)page8, length, &header);
3820Sstevel@tonic-gate if (status != 0) {
3830Sstevel@tonic-gate err_print("Mode select failed\n");
3840Sstevel@tonic-gate return (0);
3850Sstevel@tonic-gate }
3860Sstevel@tonic-gate }
3870Sstevel@tonic-gate } else {
3880Sstevel@tonic-gate err_print("Read cache setting is not changeable\n");
3890Sstevel@tonic-gate }
3900Sstevel@tonic-gate }
3910Sstevel@tonic-gate if (status != 0) {
3920Sstevel@tonic-gate err_print("Mode sense failed.\n");
3930Sstevel@tonic-gate }
3940Sstevel@tonic-gate return (0);
3950Sstevel@tonic-gate }
396