1*24db4641Seschrock /* 2*24db4641Seschrock * CDDL HEADER START 3*24db4641Seschrock * 4*24db4641Seschrock * The contents of this file are subject to the terms of the 5*24db4641Seschrock * Common Development and Distribution License (the "License"). 6*24db4641Seschrock * You may not use this file except in compliance with the License. 7*24db4641Seschrock * 8*24db4641Seschrock * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*24db4641Seschrock * or http://www.opensolaris.org/os/licensing. 10*24db4641Seschrock * See the License for the specific language governing permissions 11*24db4641Seschrock * and limitations under the License. 12*24db4641Seschrock * 13*24db4641Seschrock * When distributing Covered Code, include this CDDL HEADER in each 14*24db4641Seschrock * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*24db4641Seschrock * If applicable, add the following below this CDDL HEADER, with the 16*24db4641Seschrock * fields enclosed by brackets "[]" replaced with your own identifying 17*24db4641Seschrock * information: Portions Copyright [yyyy] [name of copyright owner] 18*24db4641Seschrock * 19*24db4641Seschrock * CDDL HEADER END 20*24db4641Seschrock */ 21*24db4641Seschrock /* 22*24db4641Seschrock * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23*24db4641Seschrock * Use is subject to license terms. 24*24db4641Seschrock */ 25*24db4641Seschrock 26*24db4641Seschrock #ifndef _DS_SCSI_H 27*24db4641Seschrock #define _DS_SCSI_H 28*24db4641Seschrock 29*24db4641Seschrock #pragma ident "%Z%%M% %I% %E% SMI" 30*24db4641Seschrock 31*24db4641Seschrock #include <sys/types.h> 32*24db4641Seschrock #include <sys/byteorder.h> 33*24db4641Seschrock #include <sys/scsi/scsi.h> 34*24db4641Seschrock 35*24db4641Seschrock #include "ds_impl.h" 36*24db4641Seschrock 37*24db4641Seschrock #ifdef __cplusplus 38*24db4641Seschrock extern "C" { 39*24db4641Seschrock #endif 40*24db4641Seschrock 41*24db4641Seschrock #if !defined(_BIT_FIELDS_LTOH) && !defined(_BIT_FIELDS_HTOL) 42*24db4641Seschrock #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 43*24db4641Seschrock #endif 44*24db4641Seschrock 45*24db4641Seschrock /* 46*24db4641Seschrock * Log page structures 47*24db4641Seschrock */ 48*24db4641Seschrock #pragma pack(1) 49*24db4641Seschrock 50*24db4641Seschrock typedef struct scsi_log_header { 51*24db4641Seschrock #if defined(_BIT_FIELDS_LTOH) 52*24db4641Seschrock uint8_t lh_code : 6, 53*24db4641Seschrock __reserved : 2; 54*24db4641Seschrock #else 55*24db4641Seschrock uint8_t __reserved : 2, 56*24db4641Seschrock lh_code : 6; 57*24db4641Seschrock #endif 58*24db4641Seschrock uint8_t __reserved2; 59*24db4641Seschrock uint16_t lh_length; 60*24db4641Seschrock } scsi_log_header_t; 61*24db4641Seschrock 62*24db4641Seschrock typedef struct scsi_log_parameter_header { 63*24db4641Seschrock uint16_t lph_param; 64*24db4641Seschrock #if defined(_BIT_FIELDS_LTOH) 65*24db4641Seschrock uint8_t lph_lp : 1, 66*24db4641Seschrock lph_lbin : 1, 67*24db4641Seschrock lph_tmc : 2, 68*24db4641Seschrock lph_etc : 1, 69*24db4641Seschrock lph_tsd : 1, 70*24db4641Seschrock lph_ds : 1, 71*24db4641Seschrock lph_du : 1; 72*24db4641Seschrock #else 73*24db4641Seschrock uint8_t lph_du : 1, 74*24db4641Seschrock lph_ds : 1, 75*24db4641Seschrock lph_tsd : 1, 76*24db4641Seschrock lph_etc : 1, 77*24db4641Seschrock lph_tmc : 2, 78*24db4641Seschrock lph_lbin : 1, 79*24db4641Seschrock lph_lp : 1; 80*24db4641Seschrock #endif 81*24db4641Seschrock uint8_t lph_length; 82*24db4641Seschrock } scsi_log_parameter_header_t; 83*24db4641Seschrock 84*24db4641Seschrock typedef struct scsi_supported_log_pages { 85*24db4641Seschrock scsi_log_header_t slp_hdr; 86*24db4641Seschrock uchar_t slp_pages[1]; 87*24db4641Seschrock } scsi_supported_log_pages_t; 88*24db4641Seschrock 89*24db4641Seschrock typedef struct scsi_ie_log_param { 90*24db4641Seschrock scsi_log_parameter_header_t ie_hdr; 91*24db4641Seschrock uchar_t ie_asc; 92*24db4641Seschrock uchar_t ie_ascq; 93*24db4641Seschrock } scsi_ie_log_param_t; 94*24db4641Seschrock 95*24db4641Seschrock /* 96*24db4641Seschrock * The SCSI-3 SPC document states that IE log page (0x2F) parameter 0 97*24db4641Seschrock * must have a length of at least 4 (including the length byte). 98*24db4641Seschrock */ 99*24db4641Seschrock #define LOGPARAM_IE_MIN_LEN 2 /* the asc and ascq fields */ 100*24db4641Seschrock 101*24db4641Seschrock #define INVALID_TEMPERATURE 0xff 102*24db4641Seschrock 103*24db4641Seschrock #define LOGPARAM_IE 0x0000 104*24db4641Seschrock 105*24db4641Seschrock typedef struct scsi_temp_log_param { 106*24db4641Seschrock scsi_log_parameter_header_t t_hdr; 107*24db4641Seschrock uchar_t __reserved; 108*24db4641Seschrock uchar_t t_temp; 109*24db4641Seschrock } scsi_temp_log_param_t; 110*24db4641Seschrock 111*24db4641Seschrock typedef struct scsi_selftest_log_param { 112*24db4641Seschrock scsi_log_parameter_header_t st_hdr; 113*24db4641Seschrock #if defined(_BIT_FIELDS_LTOH) 114*24db4641Seschrock uint8_t st_results : 4, 115*24db4641Seschrock __reserved1 : 1, 116*24db4641Seschrock st_testcode : 3; 117*24db4641Seschrock #else 118*24db4641Seschrock uint8_t st_testcode : 3, 119*24db4641Seschrock __reserved1 : 1, 120*24db4641Seschrock st_results : 4; 121*24db4641Seschrock #endif 122*24db4641Seschrock uint8_t st_number; 123*24db4641Seschrock uint16_t st_timestamp; 124*24db4641Seschrock uint64_t st_lba; 125*24db4641Seschrock #if defined(_BIT_FIELDS_LTOH) 126*24db4641Seschrock uint8_t st_sensekey : 4, 127*24db4641Seschrock __reserved2 : 4; 128*24db4641Seschrock #else 129*24db4641Seschrock uint8_t __reserved2 : 4, 130*24db4641Seschrock st_sensekey : 4; 131*24db4641Seschrock #endif 132*24db4641Seschrock uint8_t st_asc; 133*24db4641Seschrock uint8_t st_ascq; 134*24db4641Seschrock uint8_t st_vendor; 135*24db4641Seschrock } scsi_selftest_log_param_t; 136*24db4641Seschrock 137*24db4641Seschrock /* The results field of the self-test log parameter */ 138*24db4641Seschrock #define SELFTEST_OK 0x0 139*24db4641Seschrock #define SELFTEST_ABORT_REQUEST 0x1 140*24db4641Seschrock #define SELFTEST_ABORT_OTHER 0x2 141*24db4641Seschrock #define SELFTEST_FAILURE_INCOMPLETE 0x3 142*24db4641Seschrock #define SELFTEST_FAILURE_SEG_UNKNOWN 0x4 143*24db4641Seschrock #define SELFTEST_FAILURE_SEG_FIRST 0x5 144*24db4641Seschrock #define SELFTEST_FAILURE_SEG_SECOND 0x6 145*24db4641Seschrock #define SELFTEST_FAILURE_SEG_OTHER 0x7 146*24db4641Seschrock #define SELFTEST_INPROGRESS 0xf 147*24db4641Seschrock 148*24db4641Seschrock #define SELFTEST_COMPLETE(code) \ 149*24db4641Seschrock ((code) == SELFTEST_OK || \ 150*24db4641Seschrock ((code) >= SELFTEST_FAILURE_INCOMPLETE && \ 151*24db4641Seschrock ((code) <= SELFTEST_FAILURE_SEG_OTHER))) 152*24db4641Seschrock 153*24db4641Seschrock #define LOGPARAM_TEMP_CURTEMP 0x0000 154*24db4641Seschrock #define LOGPARAM_TEMP_REFTEMP 0x0001 155*24db4641Seschrock 156*24db4641Seschrock #define LOGPARAM_TEMP_LEN \ 157*24db4641Seschrock (sizeof (scsi_temp_log_param_t) - \ 158*24db4641Seschrock sizeof (scsi_log_parameter_header_t)) 159*24db4641Seschrock 160*24db4641Seschrock /* 161*24db4641Seschrock * Mode sense/select page header information 162*24db4641Seschrock */ 163*24db4641Seschrock typedef struct scsi_ms_header { 164*24db4641Seschrock struct mode_header ms_header; 165*24db4641Seschrock struct block_descriptor ms_descriptor; 166*24db4641Seschrock } scsi_ms_header_t; 167*24db4641Seschrock 168*24db4641Seschrock typedef struct scsi_ms_header_g1 { 169*24db4641Seschrock struct mode_header_g1 ms_header; 170*24db4641Seschrock struct block_descriptor ms_descriptor; 171*24db4641Seschrock } scsi_ms_header_g1_t; 172*24db4641Seschrock 173*24db4641Seschrock typedef struct scsi_ms_hdrs { 174*24db4641Seschrock int ms_length; 175*24db4641Seschrock union { 176*24db4641Seschrock scsi_ms_header_t g0; 177*24db4641Seschrock scsi_ms_header_g1_t g1; 178*24db4641Seschrock } ms_hdr; 179*24db4641Seschrock } scsi_ms_hdrs_t; 180*24db4641Seschrock 181*24db4641Seschrock typedef struct scsi_ie_page { 182*24db4641Seschrock struct mode_page ie_mp; 183*24db4641Seschrock #if defined(_BIT_FIELDS_LTOH) 184*24db4641Seschrock uint8_t ie_logerr : 1, /* Errors should be logged */ 185*24db4641Seschrock __reserved1 : 1, 186*24db4641Seschrock ie_test : 1, /* Enable test gen of IEs */ 187*24db4641Seschrock ie_dexcpt : 1, /* Disable exceptions */ 188*24db4641Seschrock ie_ewasc : 1, /* Enable warning generation */ 189*24db4641Seschrock ie_ebf : 1, /* enable backgrnd functions */ 190*24db4641Seschrock __reserved2 : 1, 191*24db4641Seschrock ie_perf : 1; /* No delays during excptns */ 192*24db4641Seschrock uint8_t ie_mrie : 4, /* Method/reporting excptons */ 193*24db4641Seschrock __reserved3 : 4; 194*24db4641Seschrock #else 195*24db4641Seschrock uint8_t ie_perf : 1, /* No delays during excptons */ 196*24db4641Seschrock __reserved2 : 1, 197*24db4641Seschrock ie_ebf : 1, /* enable background funcs */ 198*24db4641Seschrock ie_ewasc : 1, /* Enable warning generation */ 199*24db4641Seschrock ie_dexcpt : 1, /* Disable exceptions */ 200*24db4641Seschrock ie_test : 1, /* Enable test gen of IEs */ 201*24db4641Seschrock __reserved1 : 1, 202*24db4641Seschrock ie_logerr : 1; /* Errors should be logged */ 203*24db4641Seschrock uint8_t __reserved3 : 4, 204*24db4641Seschrock ie_mrie : 4; /* Method of report excptns */ 205*24db4641Seschrock #endif 206*24db4641Seschrock uint32_t ie_interval_timer; /* reporting interval for IEs */ 207*24db4641Seschrock uint32_t ie_report_count; /* # of times to report an IE */ 208*24db4641Seschrock } scsi_ie_page_t; 209*24db4641Seschrock 210*24db4641Seschrock #pragma pack() 211*24db4641Seschrock 212*24db4641Seschrock #define MODEPAGE_INFO_EXCPT_LEN (sizeof (scsi_ie_page_t)) 213*24db4641Seschrock 214*24db4641Seschrock #define IEC_IE_ENABLED(ies) ((ies).ie_dexcpt == 0) 215*24db4641Seschrock #define IEC_IE_CHANGEABLE(ies) ((ies).ie_dexcpt == 1) 216*24db4641Seschrock #define IEC_MRIE_CHANGEABLE(ies) ((ies).ie_mrie == 0xf) 217*24db4641Seschrock #define IEC_PERF_CHANGEABLE(ies) ((ies).ie_perf == 1) 218*24db4641Seschrock #define IEC_EWASC_CHANGEABLE(ies) ((ies).ie_ewasc == 1) 219*24db4641Seschrock #define IEC_TEST_CHANGEABLE(ies) ((ies).ie_test == 1) 220*24db4641Seschrock #define IEC_RPTCNT_CHANGEABLE(ies) ((ies).ie_report_count == BE_32(0xffffffff)) 221*24db4641Seschrock #define IEC_LOGERR_CHANGEABLE(ies) ((ies).ie_logerr == 1) 222*24db4641Seschrock 223*24db4641Seschrock /* 224*24db4641Seschrock * Values for the MRIE field of the informational exceptions control mode page 225*24db4641Seschrock */ 226*24db4641Seschrock #define IE_REPORT_NONE 0 227*24db4641Seschrock #define IE_REPORT_ASYNCH 1 228*24db4641Seschrock #define IE_REPORT_UNIT_ATTN 2 229*24db4641Seschrock #define IE_REPORT_RECOV_ERR_COND 3 230*24db4641Seschrock #define IE_REPORT_RECOV_ERR_ALWAYS 4 231*24db4641Seschrock #define IE_REPORT_NO_SENSE 5 232*24db4641Seschrock #define IE_REPORT_ON_REQUEST 6 233*24db4641Seschrock 234*24db4641Seschrock /* 235*24db4641Seschrock * Constants in support of the CONTROL MODE mode page (page 0xA) 236*24db4641Seschrock */ 237*24db4641Seschrock #define MODEPAGE_CTRL_MODE_LEN (sizeof (struct mode_control_scsi3)) 238*24db4641Seschrock #define GLTSD_CHANGEABLE(chg) ((chg).gltsd == 1) 239*24db4641Seschrock 240*24db4641Seschrock #define LOGPAGE_SELFTEST_MIN_PARAM_CODE 0x0001 241*24db4641Seschrock #define LOGPAGE_SELFTEST_MAX_PARAM_CODE 0x0014 242*24db4641Seschrock 243*24db4641Seschrock #define LOGPAGE_SELFTEST_PARAM_LEN \ 244*24db4641Seschrock ((sizeof (scsi_selftest_log_param_t)) - \ 245*24db4641Seschrock (sizeof (scsi_log_parameter_header_t))) 246*24db4641Seschrock 247*24db4641Seschrock /* 248*24db4641Seschrock * Macro to extract the length of a mode sense page 249*24db4641Seschrock * as returned by a target. 250*24db4641Seschrock */ 251*24db4641Seschrock #define MODESENSE_PAGE_LEN(p) (((int)((struct mode_page *)p)->length) + \ 252*24db4641Seschrock sizeof (struct mode_page)) 253*24db4641Seschrock 254*24db4641Seschrock /* 255*24db4641Seschrock * Mode Select options 256*24db4641Seschrock */ 257*24db4641Seschrock #define MODE_SELECT_SP 0x01 258*24db4641Seschrock #define MODE_SELECT_PF 0x10 259*24db4641Seschrock 260*24db4641Seschrock 261*24db4641Seschrock /* 262*24db4641Seschrock * Mode Sense Page Control 263*24db4641Seschrock */ 264*24db4641Seschrock #define PC_CURRENT (0 << 6) 265*24db4641Seschrock #define PC_CHANGEABLE (1 << 6) 266*24db4641Seschrock #define PC_DEFAULT (2 << 6) 267*24db4641Seschrock #define PC_SAVED (3 << 6) 268*24db4641Seschrock 269*24db4641Seschrock /* 270*24db4641Seschrock * Log Sense Page Control 271*24db4641Seschrock */ 272*24db4641Seschrock #define PC_CUMULATIVE (1 << 6) 273*24db4641Seschrock 274*24db4641Seschrock /* 275*24db4641Seschrock * LOG page codes 276*24db4641Seschrock */ 277*24db4641Seschrock #define LOGPAGE_SUPP_LIST 0x00 278*24db4641Seschrock #define LOGPAGE_TEMP 0x0d 279*24db4641Seschrock #define LOGPAGE_SELFTEST 0x10 280*24db4641Seschrock #define LOGPAGE_IE 0x2f 281*24db4641Seschrock 282*24db4641Seschrock /* ASC constants */ 283*24db4641Seschrock #define ASC_INVALID_OPCODE 0x20 284*24db4641Seschrock #define ASC_INVALID_CDB_FIELD 0x24 285*24db4641Seschrock #define ASC_FAILURE_PREDICTION_THRESHOLD_EXCEEDED 0x5d 286*24db4641Seschrock 287*24db4641Seschrock /* ASCQ constants */ 288*24db4641Seschrock #define ASCQ_INVALID_OPCODE 0 289*24db4641Seschrock 290*24db4641Seschrock /* Error tests */ 291*24db4641Seschrock #define SCSI_INVALID_OPCODE(s, a, aq) \ 292*24db4641Seschrock (((s) == KEY_ILLEGAL_REQUEST) && ((a) == ASC_INVALID_OPCODE) && \ 293*24db4641Seschrock ((aq) == ASCQ_INVALID_OPCODE)) 294*24db4641Seschrock 295*24db4641Seschrock #define MODE_PAGE_UNSUPPORTED(s, a, aq) \ 296*24db4641Seschrock (((s) == KEY_ILLEGAL_REQUEST) && ((a) == ASC_INVALID_CDB_FIELD)) 297*24db4641Seschrock 298*24db4641Seschrock /* command length to use */ 299*24db4641Seschrock #define MODE_CMD_LEN_UNKNOWN 0 300*24db4641Seschrock #define MODE_CMD_LEN_6 1 301*24db4641Seschrock #define MODE_CMD_LEN_10 2 302*24db4641Seschrock 303*24db4641Seschrock /* supported modepages bitmask */ 304*24db4641Seschrock #define MODEPAGE_SUPP_IEC 0x1 305*24db4641Seschrock 306*24db4641Seschrock /* supported logpages bitmask */ 307*24db4641Seschrock #define LOGPAGE_SUPP_IE 0x1 308*24db4641Seschrock #define LOGPAGE_SUPP_TEMP 0x2 309*24db4641Seschrock #define LOGPAGE_SUPP_SELFTEST 0x4 310*24db4641Seschrock 311*24db4641Seschrock #define MSG_BUFLEN 256 312*24db4641Seschrock 313*24db4641Seschrock /* 314*24db4641Seschrock * For SCSI commands which want to accept arbitrary length responses, we need to 315*24db4641Seschrock * allocate an appropriate sized buffer. The maximum length is USHRT_MAX, 316*24db4641Seschrock * because some devices return nothing if the buffer length is too big. 317*24db4641Seschrock */ 318*24db4641Seschrock #define MAX_BUFLEN(type) (USHRT_MAX - sizeof (type)) 319*24db4641Seschrock 320*24db4641Seschrock extern ds_transport_t ds_scsi_uscsi_transport; 321*24db4641Seschrock extern ds_transport_t ds_scsi_sim_transport; 322*24db4641Seschrock 323*24db4641Seschrock #ifdef __cplusplus 324*24db4641Seschrock } 325*24db4641Seschrock #endif 326*24db4641Seschrock 327*24db4641Seschrock #endif /* _DS_SCSI_H */ 328