1/* $OpenBSD: ses.h,v 1.10 2006/05/11 00:45:59 krw Exp $ */ 2/* 3 * Copyright (c) 2005 Marco Peereboom 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR 19 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 29#ifndef _SCSI_SES_H_ 30#define _SCSI_SES_H_ 31 32/* the scsi command */ 33struct ses_scsi_diag { 34 u_int8_t opcode; /* SEND_DIAGNOSTIC or RECEIVE_DIAGNOSTIC */ 35 u_int8_t flags; 36#define SES_DIAG_PCV (1<<0) /* page code valid */ 37#define SES_DIAG_PF (1<<4) /* set this bit if page code is valid */ 38 u_int8_t pgcode; 39#define SES_PAGE_CONFIG 0x01 /* Configuration */ 40#define SES_PAGE_STATUS 0x02 /* Enclosure Status */ 41#define SES_PAGE_EDESC 0x07 /* Element Descriptor */ 42 u_int16_t length; 43 u_int8_t control; 44} __packed; 45 46 47/* all the different sensor types */ 48#define SES_T_UNSPEC 0x00 49#define SES_T_DEVICE 0x01 50#define SES_T_POWERSUPPLY 0x02 51#define SES_T_COOLING 0x03 52#define SES_T_TEMP 0x04 53#define SES_T_DOORLOCK 0x05 54#define SES_T_ALARM 0x06 55#define SES_T_ENC_SRV_CTRL 0x07 56#define SES_T_SCC_CTRL 0x08 57#define SES_T_NONVOL_CACHE 0x09 58#define SES_T_INV_OP_REASON 0x0a 59#define SES_T_UPS 0x0b 60#define SES_T_DISPLAY 0x0c 61#define SES_T_KEYPAD 0x0d 62#define SES_T_ENCLOSURE 0x0e 63#define SES_T_SCSI_PORT_TRANS 0x0f 64#define SES_T_LANGUAGE 0x10 65#define SES_T_COMM_PORT 0x11 66#define SES_T_VOLTAGE 0x12 67#define SES_T_CURRENT 0x13 68#define SES_T_SCSI_TARGET_PORT 0x14 69#define SES_T_SCSI_INIT_PORT 0x15 70#define SES_T_SIMP_SUBENC 0x16 71#define SES_T_ARRAY_DEVICE 0x17 72 73#define SES_NUM_TYPES 256 74 75/* diagnostic page header */ 76struct ses_config_hdr { 77 u_int8_t pgcode; /* SES_PAGE_CONFIG */ 78 u_int8_t n_subenc; 79 u_int16_t length; 80 u_int32_t gencode; 81} __packed; 82#define SES_CFG_HDRLEN sizeof(struct ses_config_hdr) 83 84/* enclosure descriptor header */ 85struct ses_enc_hdr { 86 u_int8_t enc_id; 87 u_int8_t subenc_id; 88 u_int8_t n_types; 89 u_int8_t vendor_len; 90} __packed; 91#define SES_ENC_HDRLEN sizeof(struct ses_enc_hdr) 92 93/* enclosure descriptor strings */ 94struct ses_enc_desc { 95 u_int8_t logical_id[8]; /* this isnt a string */ 96 u_int8_t vendor_id[8]; 97 u_int8_t prod_id[16]; 98 u_int8_t prod_rev[4]; 99 u_int8_t vendor[0]; 100} __packed; 101 102/* type descriptor header */ 103struct ses_type_desc { 104 u_int8_t type; 105 u_int8_t n_elem; 106 u_int8_t subenc_id; 107 u_int8_t desc_len; 108} __packed; 109#define SES_TYPE_DESCLEN sizeof(struct ses_type_desc) 110 111/* status page header */ 112struct ses_status_hdr { 113 u_int8_t pgcode; /* SES_PAGE_STATUS */ 114 u_int8_t flags; 115#define SES_STAT_UNRECOV (1<<0) /* unrecoverable error */ 116#define SES_STAT_CRIT (1<<1) /* critical error */ 117#define SES_STAT_NONCRIT (1<<2) /* noncritical error */ 118#define SES_STAT_INFO (1<<3) /* info available */ 119#define SES_STAT_INVOP (1<<4) /* invalid operation */ 120 u_int16_t length; 121 u_int32_t gencode; 122} __packed; 123#define SES_STAT_HDRLEN sizeof(struct ses_status_hdr) 124 125struct ses_status { 126 u_int8_t com; 127#define SES_STAT_CODE_MASK 0x0f 128#define SES_STAT_CODE(x) ((x) & SES_STAT_CODE_MASK) 129#define SES_STAT_CODE_UNSUP 0x00 /* unsupported */ 130#define SES_STAT_CODE_OK 0x01 /* installed and ok */ 131#define SES_STAT_CODE_CRIT 0x02 /* critical */ 132#define SES_STAT_CODE_NONCRIT 0x03 /* warning */ 133#define SES_STAT_CODE_UNREC 0x04 /* unrecoverable */ 134#define SES_STAT_CODE_NOTINST 0x05 /* not installed */ 135#define SES_STAT_CODE_UNKNOWN 0x06 /* unknown */ 136#define SES_STAT_CODE_NOTAVAIL 0x07 /* not available */ 137#define SES_STAT_SWAP (1<<4) /* element has been swapped */ 138#define SES_STAT_DISABLED (1<<5) /* disabled */ 139#define SES_STAT_PRDFAIL (1<<6) /* predicted failure */ 140#define SES_STAT_SELECT (1<<7) /* set to modify element */ 141 142 u_int8_t f1; /* use of these flags depends on the SES_T */ 143 u_int8_t f2; 144 u_int8_t f3; 145} __packed; 146#define SES_STAT_ELEMLEN sizeof(struct ses_status) 147 148/* device status */ 149/* f1 is the device address */ 150/* f2 */ 151#define SES_S_DEV_REPORT (1<<0) /* enc report in progress */ 152#define SES_S_DEV_IDENT (1<<1) /* currently identifying */ 153#define SES_S_DEV_REMOVE (1<<2) /* ready to remove */ 154#define SES_S_DEV_INSERT (1<<3) /* ready to insert */ 155#define SES_S_DEV_ENCBYPB (1<<4) /* port B bypassed by enc */ 156#define SES_S_DEV_ENCBYPA (1<<5) /* port A bypassed by enc */ 157#define SES_S_DEV_DONOTREM (1<<6) /* do not remove */ 158#define SES_S_DEV_APPCLBYPA (1<<7) /* port A bypassed by app */ 159/* f3 */ 160#define SES_S_DEV_DEVBYPB (1<<0) /* port B bypassed by dev */ 161#define SES_S_DEV_DEVBYPA (1<<1) /* port A bypassed by dev */ 162#define SES_S_DEV_BYPB (1<<2) 163#define SES_S_DEV_BYPA (1<<3) 164#define SES_S_DEV_OFF (1<<4) /* device is off */ 165#define SES_S_DEV_FAULTRQST (1<<5) /* fault indicator rqsted */ 166#define SES_S_DEV_FAULTSENSE (1<<6) /* fault sensed */ 167#define SES_S_DEV_APPCLBYPB (1<<7) /* port B bypassed by app */ 168 169/* device configuration */ 170/* f1 is reserved */ 171/* f2 */ 172#define SES_C_DEV_IDENT (1<<1) /* ident */ 173#define SES_C_DEV_REMOVE (1<<2) /* remove */ 174#define SES_C_DEV_INSERT (1<<3) /* insert */ 175#define SES_C_DEV_DONOTREM (1<<6) /* do not remove */ 176#define SES_C_DEV_ACTIVE (1<<7) /* active indicator */ 177#define SES_C_DEV_F2MASK (SES_C_DEV_IDENT | SES_C_DEV_REMOVE | \ 178 SES_C_DEV_INSERT | SES_C_DEV_DONOTREM | SES_C_DEV_ACTIVE ) 179/* f3 */ 180#define SES_C_DEV_BYPB (1<<2) /* port B bypass */ 181#define SES_C_DEV_BYPA (1<<3) /* port A bypass */ 182#define SES_C_DEV_OFF (1<<4) /* off */ 183#define SES_C_DEV_FAULT (1<<5) /* fault indicator */ 184#define SES_C_DEV_F3MASK (SES_C_DEV_BYPB | SES_C_DEV_BYPA | \ 185 SES_C_DEV_OFF | SES_C_DEV_FAULT) 186 187/* power supply element */ 188#define SES_S_PSU_IDENT(d) ((d)->f1 & (1<<6)) /* identify */ 189#define SES_S_PSU_DCOC(d) ((d)->f2 & (1<<1)) /* DC over current */ 190#define SES_S_PSU_DCUV(d) ((d)->f2 & (1<<2)) /* DC under voltage */ 191#define SES_S_PSU_DCOV(d) ((d)->f2 & (1<<3)) /* DC over voltage */ 192#define SES_S_PSU_DCFAIL(d) ((d)->f3 & (1<<0)) /* DC fail */ 193#define SES_S_PSU_ACFAIL(d) ((d)->f3 & (1<<1)) /* AC fail */ 194#define SES_S_PSU_TEMPWARN(d) ((d)->f3 & (1<<2)) /* Temp warn */ 195#define SES_S_PSU_OVERTEMP(d) ((d)->f3 & (1<<3)) /* over temp fail */ 196#define SES_S_PSU_OFF(d) ((d)->f3 & (1<<4)) /* is the unit off */ 197#define SES_S_PSU_RQSTON(d) ((d)->f3 & (1<<5)) /* manually on */ 198#define SES_S_PSU_FAIL(d) ((d)->f3 & (1<<6)) /* fail is set on */ 199 200/* cooling element */ 201#define SES_S_COOL_IDENT(d) ((d)->f1 & (1<<6)) /* identify */ 202#define SES_S_COOL_SPEED_MASK 0x03 203#define SES_S_COOL_SPEED(d) ((d)->f2 + \ 204 ((u_int16_t)((d)->f2 & SES_S_COOL_SPEED_MASK) << 8)) 205#define SES_S_COOL_FACTOR 10 206#define SES_S_COOL_CODE(d) ((d)->f3 & 0x7) /* actual speed code */ 207#define SES_S_COOL_C_STOPPED 0x0 /* stopped */ 208#define SES_S_COOL_C_LOW1 0x1 /* lowest speed */ 209#define SES_S_COOL_C_LOW2 0x2 /* second lowest speed */ 210#define SES_S_COOL_C_LOW3 0x3 /* third lowest speed */ 211#define SES_S_COOL_C_INTER 0x4 /* intermediate speed */ 212#define SES_S_COOL_C_HI3 0x5 /* third highest speed */ 213#define SES_S_COOL_C_HI2 0x6 /* second highest speed */ 214#define SES_S_COOL_C_HI1 0x7 /* highest speed */ 215#define SES_S_COOL_OFF ((d)->f3 & (1<<4)) /* not cooling */ 216#define SES_S_COOL_RQSTON ((d)->f3 & (1<<5)) /* manually on */ 217#define SES_S_COOL_FAIL ((d)->f3 & (1<<6)) /* fail indic is on */ 218 219/* temperature sensor */ 220#define SES_S_TEMP_IDENT(d) ((d)->f1 & (1<<7)) /* identify */ 221#define SES_S_TEMP(d) ((d)->f2) 222#define SES_S_TEMP_OFFSET (-20) 223#define SES_S_TEMP_UTWARN ((d)->f3 & (1<<0)) /* under temp warning */ 224#define SES_S_TEMP_UTFAIL ((d)->f3 & (1<<1)) /* under temp failure */ 225#define SES_S_TEMP_OTWARN ((d)->f3 & (1<<2)) /* over temp warning */ 226#define SES_S_TEMP_OTFAIL ((d)->f3 & (1<<3)) /* over temp failure */ 227 228/* 229 * the length of the status page is the header and a status element for 230 * each type plus the number of elements for each type 231 */ 232#define SES_STAT_LEN(t, e) \ 233 (SES_STAT_HDRLEN + SES_STAT_ELEMLEN * ((t)+(e))) 234 235#endif /* _SCSI_SES_H_ */ 236