| 1 | /* $OpenBSD: ses.h,v 1.11 2024/09/04 07:54:53 mglocker 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 */ |
| 33 | struct 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 */ |
| 76 | struct 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 */ |
| 85 | struct 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 */ |
| 94 | struct ses_enc_desc { |
| 95 | 	u_int8_t	logical_id[8]; /* this isn't 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 */ |
| 103 | struct 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 */ |
| 112 | struct 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 | |
| 125 | struct 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_ */ |