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 */
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 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 */
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_ */