1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 /*
26  * Copyright 2019 RackTop Systems
27  */
28 
29 #ifndef	_PLUGIN_SES_IMPL_H
30 #define	_PLUGIN_SES_IMPL_H
31 
32 #ifdef	__cplusplus
33 extern "C" {
34 #endif
35 
36 #include <sys/types.h>
37 #include <sys/sysmacros.h>
38 #include <sys/scsi/impl/uscsi.h>
39 #include <sys/scsi/generic/commands.h>
40 #include <sys/scsi/impl/spc3_types.h>
41 #include <sys/ccompile.h>
42 #include <stdarg.h>
43 #include <libnvpair.h>
44 
45 #include <scsi/libscsi.h>
46 #include <scsi/libses_plugin.h>
47 
48 #pragma	pack(1)
49 
50 /*
51  * Generic IO timeout in seconds, from <sys/scsi/targets/ses.h>.
52  */
53 #define	SES2_TIMEOUT	60
54 
55 /*
56  * SES-2 Enclosure Descriptor Header (Table 8, 6.1.2.2)
57  */
58 typedef struct ses2_ed_hdr_impl {
59 	DECL_BITFIELD4(
60 	    sehi_n_esps		:3,
61 	    _reserved1		:1,
62 	    sehi_rel_esp_id	:3,
63 	    _reserved2		:1);
64 	uint8_t sehi_subenclosure_id;
65 	uint8_t sehi_n_etd_hdrs;
66 	uint8_t sehi_ed_len;
67 } ses2_ed_hdr_impl_t;
68 
69 /*
70  * SES-2 Enclosure Descriptor (Table 8, 6.1.2.2)
71  */
72 typedef struct ses2_ed_impl {
73 	ses2_ed_hdr_impl_t st_hdr;
74 	spc3_naa_id_8_impl_t st_logical_id;
75 	char st_vendor_id[8];
76 	char st_product_id[16];
77 	char st_product_revision[4];
78 	uint8_t st_priv[1];
79 } ses2_ed_impl_t;
80 
81 /*
82  * SES-2 Type Descriptor Header (Table 9, 6.1.2.3)
83  */
84 typedef struct ses2_td_hdr_impl {
85 	uint8_t sthi_element_type;
86 	uint8_t sthi_max_elements;
87 	uint8_t sthi_subenclosure_id;
88 	uint8_t sthi_text_len;
89 } ses2_td_hdr_impl_t;
90 
91 /*
92  * SES-2 Configuration diagnostic page (Table 7, 6.1.2.1)
93  */
94 typedef struct ses2_config_page_impl {
95 	uint8_t scpi_page_code;
96 	uint8_t scpi_n_subenclosures;
97 	uint16_t scpi_page_length;
98 	uint32_t scpi_generation_code;
99 	uint8_t scpi_data[1];
100 } ses2_config_page_impl_t;
101 
102 /*
103  * Logically we should be able to use 4 or 8 bytes for a minimum allocation;
104  * however, it seems at least some devices will fail the request in that case.
105  */
106 #define	SES2_MIN_DIAGPAGE_ALLOC 512
107 
108 /*
109  * SES-2 Element Control and Overall Control fields (Table 59, 7.2.2)
110  */
111 typedef struct ses2_cmn_elem_ctl_impl {
112 	DECL_BITFIELD5(
113 	    _reserved1		:4,
114 	    seci_rst_swap	:1,
115 	    seci_disable	:1,
116 	    seci_prdfail	:1,
117 	    seci_select		:1);
118 } ses2_cmn_elem_ctl_impl_t;
119 
120 typedef struct ses2_elem_ctl_impl {
121 	ses2_cmn_elem_ctl_impl_t seci_common;
122 	uint8_t seci_data[3];
123 } ses2_elem_ctl_impl_t;
124 
125 /*
126  * SES-2 Element Status and Overall Status fields (Table 60, 7.2.3)
127  */
128 typedef struct ses2_cmn_elem_status_impl {
129 	DECL_BITFIELD5(
130 	    sesi_status_code	:4,
131 	    sesi_swap		:1,
132 	    sesi_disabled	:1,
133 	    sesi_prdfail	:1,
134 	    _reserved1		:1);
135 } ses2_cmn_elem_status_impl_t;
136 
137 typedef struct ses2_elem_status_impl {
138 	ses2_cmn_elem_status_impl_t sesi_common;
139 	uint8_t sesi_data[3];
140 } ses2_elem_status_impl_t;
141 
142 /*
143  * SES-2 Device element for the Enclosure Control diagnostic page.
144  */
145 typedef struct ses2_device_ctl_impl {
146 	ses2_cmn_elem_ctl_impl_t sdci_common;
147 	uint8_t _reserved1;
148 	DECL_BITFIELD8(
149 	    _reserved2		:1,
150 	    sdci_rqst_ident	:1,
151 	    sdci_rqst_remove	:1,
152 	    sdci_rqst_insert	:1,
153 	    sdci_rqst_missing	:1,
154 	    _reserved3		:1,
155 	    sdci_do_not_remove	:1,
156 	    sdci_rqst_active	:1);
157 	DECL_BITFIELD6(
158 	    _reserved4		:2,
159 	    sdci_enable_byp_b	:1,
160 	    sdci_enable_byp_a	:1,
161 	    sdci_device_off	:1,
162 	    sdci_rqst_fault	:1,
163 	    _reserved5		:2);
164 } ses2_device_ctl_impl_t;
165 
166 /*
167  * SES-2 Device element for the Enclosure Status diagnostic page
168  * (Table 64, 7.3.2).
169  */
170 typedef struct ses2_device_status_impl {
171 	ses2_cmn_elem_status_impl_t sdsi_common;
172 	uint8_t sdsi_slot_addr;
173 	DECL_BITFIELD8(
174 	    sdsi_report			:1,
175 	    sdsi_ident			:1,
176 	    sdsi_rmv			:1,
177 	    sdsi_ready_to_insert	:1,
178 	    sdsi_enclosure_bypassed_b	:1,
179 	    sdsi_enclosure_bypassed_a	:1,
180 	    sdsi_do_not_remove		:1,
181 	    sdsi_app_client_bypassed_a	:1);
182 	DECL_BITFIELD8(
183 	    sdsi_device_bypassed_b	:1,
184 	    sdsi_device_bypassed_a	:1,
185 	    sdsi_bypassed_b		:1,
186 	    sdsi_bypassed_a		:1,
187 	    sdsi_device_off		:1,
188 	    sdsi_fault_reqstd		:1,
189 	    sdsi_fault_sensed		:1,
190 	    sdsi_app_client_bypassed_b	:1);
191 } ses2_device_status_impl_t;
192 
193 typedef struct ses2_array_device_ctl_impl {
194 	ses2_cmn_elem_ctl_impl_t sadci_common;
195 	DECL_BITFIELD8(
196 	    sadci_rqst_rr_abort		:1,
197 	    sadci_rqst_rebuild		:1,
198 	    sadci_rqst_in_failed_array	:1,
199 	    sadci_rqst_in_crit_array	:1,
200 	    sadci_rqst_cons_check	:1,
201 	    sadci_rqst_hot_spare	:1,
202 	    sadci_rqst_rsvd_device	:1,
203 	    sadci_rqst_ok		:1);
204 	DECL_BITFIELD8(
205 	    _reserved1		:1,
206 	    sadci_rqst_ident	:1,
207 	    sadci_rqst_remove	:1,
208 	    sadci_rqst_insert	:1,
209 	    sadci_rqst_missing	:1,
210 	    _reserved2		:1,
211 	    sadci_do_not_remove	:1,
212 	    sadci_rqst_active	:1);
213 	DECL_BITFIELD6(
214 	    _reserved3		:2,
215 	    sadci_enable_byp_b	:1,
216 	    sadci_enable_byp_a	:1,
217 	    sadci_device_off	:1,
218 	    sadci_rqst_fault	:1,
219 	    _reserved4		:2);
220 } ses2_array_device_ctl_impl_t;
221 
222 /*
223  * SES-2 Array Device element for the Enclosure Status diagnostic page
224  * (Table 66, 7.3.3)
225  */
226 typedef struct ses2_array_device_status_impl {
227 	ses2_cmn_elem_status_impl_t sadsi_common;
228 	DECL_BITFIELD8(
229 	    sadsi_rr_abort		:1,
230 	    sadsi_rebuild		:1,
231 	    sadsi_in_failed_array	:1,
232 	    sadsi_in_crit_array		:1,
233 	    sadsi_cons_chk		:1,
234 	    sadsi_hot_spare		:1,
235 	    sadsi_rsvd_device		:1,
236 	    sadsi_ok			:1);
237 	DECL_BITFIELD8(
238 	    sadsi_report		:1,
239 	    sadsi_ident			:1,
240 	    sadsi_rmv			:1,
241 	    sadsi_ready_to_insert	:1,
242 	    sadsi_enclosure_bypassed_b	:1,
243 	    sadsi_enclosure_bypassed_a	:1,
244 	    sadsi_do_not_remove		:1,
245 	    sadsi_app_client_bypassed_a	:1);
246 	DECL_BITFIELD8(
247 	    sadsi_device_bypassed_b	:1,
248 	    sadsi_device_bypassed_a	:1,
249 	    sadsi_bypassed_b		:1,
250 	    sadsi_bypassed_a		:1,
251 	    sadsi_device_off		:1,
252 	    sadsi_fault_reqstd		:1,
253 	    sadsi_fault_sensed		:1,
254 	    sadsi_app_client_bypassed_b	:1);
255 } ses2_array_device_status_impl_t;
256 
257 /*
258  * SES-2 Power Supply element for control-type diagnostic pages (T68).
259  */
260 typedef struct ses2_psu_ctl_impl {
261 	ses2_cmn_elem_ctl_impl_t spci_common;
262 	DECL_BITFIELD2(
263 	    _reserved1		:7,
264 	    spci_rqst_ident	:1);
265 	uint8_t _reserved2;
266 	DECL_BITFIELD4(
267 	    _reserved3		:5,
268 	    spci_rqst_on	:1,
269 	    spci_rqst_fail	:1,
270 	    _reserved4		:1);
271 } ses2_psu_ctl_impl_t;
272 
273 /*
274  * SES-2 Power Supply element for status-type diagnostic pages (Table 69, 7.3.4)
275  */
276 typedef struct ses2_psu_status_impl {
277 	ses2_cmn_elem_status_impl_t spsi_common;
278 	DECL_BITFIELD2(
279 	    _reserved1	:7,
280 	    spsi_ident	:1);
281 	DECL_BITFIELD5(
282 	    _reserved2			:1,
283 	    spsi_dc_over_current	:1,
284 	    spsi_dc_under_voltage	:1,
285 	    spsi_dc_over_voltage	:1,
286 	    _reserved3			:4);
287 	DECL_BITFIELD8(
288 	    spsi_dc_fail		:1,
289 	    spsi_ac_fail		:1,
290 	    spsi_temp_warn		:1,
291 	    spsi_overtmp_fail		:1,
292 	    spsi_off			:1,
293 	    spsi_rqsted_on		:1,
294 	    spsi_fail			:1,
295 	    spsi_hot_swap		:1);
296 } ses2_psu_status_impl_t;
297 
298 /*
299  * SES-2 Cooling element for control-type diagnostic pages (Table 70).
300  */
301 typedef struct ses2_cooling_ctl_impl {
302 	ses2_cmn_elem_ctl_impl_t scci_common;
303 	DECL_BITFIELD2(
304 	    _reserved1		:7,
305 	    scci_rqst_ident	:1);
306 	uint8_t _reserved2;
307 	DECL_BITFIELD5(
308 	    scci_requested_speed_code	:3,
309 	    _reserved3			:2,
310 	    scci_rqst_on		:1,
311 	    scci_rqst_fail		:1,
312 	    _reserved4			:1);
313 } ses2_cooling_ctl_impl_t;
314 
315 /*
316  * SES-2 Cooling element for status-type diagnostic pages (Table 71, 7.3.5)
317  */
318 typedef struct ses2_cooling_status_impl {
319 	ses2_cmn_elem_status_impl_t scsi_common;
320 	DECL_BITFIELD3(
321 	    scsi_fan_speed_ms3	:3,
322 	    _reserved1		:4,
323 	    scsi_ident		:1);
324 	uint8_t scsi_fan_speed_lsb;
325 	DECL_BITFIELD6(
326 	    scsi_actual_speed_code	:3,
327 	    _reserved2			:1,
328 	    scsi_off			:1,
329 	    scsi_requested_on		:1,
330 	    scsi_fail			:1,
331 	    _reserved3			:1);
332 } ses2_cooling_status_impl_t;
333 
334 /*
335  * The fan_speed fields are multiplied by this factor to obtain the actual
336  * number of RPMs.
337  */
338 #define	SES2_ES_COOLING_SPEED_FACTOR	10
339 
340 #define	SES2_ES_COOLING_ST_FAN_SPEED(csip)	\
341 	(((((uint16_t)(csip)->scsi_fan_speed_ms3) << 8) |	\
342 	    ((uint16_t)(csip)->scsi_fan_speed_lsb)) * \
343 	    (uint16_t)SES2_ES_COOLING_SPEED_FACTOR)
344 
345 /*
346  * SES-2 Temperature Sensor element for control-type diagnostic pages (T74).
347  */
348 typedef struct ses2_temp_ctl_impl {
349 	ses2_cmn_elem_ctl_impl_t stci_common;
350 	DECL_BITFIELD3(
351 	    _reserved1		:6,
352 	    stci_rqst_fail	:1,
353 	    stci_rqst_ident	:1);
354 	uint8_t _reserved2[2];
355 } ses2_temp_ctl_impl_t;
356 
357 /*
358  * SES-2 Temperature Sensor element for status-type diagnostic pages
359  * (Table 74, 7.3.6)
360  */
361 typedef struct ses2_temp_status_impl {
362 	ses2_cmn_elem_status_impl_t stsi_common;
363 	DECL_BITFIELD3(
364 	    _reserved1	:6,
365 	    stsi_fail	:1,
366 	    stsi_ident	:1);
367 	uint8_t stsi_temperature;
368 	DECL_BITFIELD4(
369 	    stsi_ut_warn	:1,
370 	    stsi_ut_fail	:1,
371 	    stsi_ot_warn	:1,
372 	    stsi_ot_fail	:1);
373 } ses2_temp_status_impl_t;
374 
375 #define	SES2_ES_TEMP_OFFSET	(-20)
376 
377 #define	SES2_ES_TEMP_ST_TEMPERATURE(tsip)	\
378 	((tsip)->stsi_temperature + SES2_ES_TEMP_OFFSET)
379 
380 /*
381  * SES-2 Door Lock element for control-type diagnostic pages (T76).
382  */
383 typedef struct ses2_lock_ctl_impl {
384 	ses2_cmn_elem_ctl_impl_t slci_common;
385 	DECL_BITFIELD3(
386 	    _reserved1		:6,
387 	    slci_rqst_fail	:1,
388 	    slci_rqst_ident	:1);
389 	uint8_t _reserved2;
390 	DECL_BITFIELD2(
391 	    slci_unlock	:1,
392 	    _reserved3	:7);
393 } ses2_lock_ctl_impl_t;
394 
395 /*
396  * SES-2 Door Lock element for status-type diagnostic pages (Table 77, 7.3.7)
397  */
398 typedef struct ses2_lock_status_impl {
399 	ses2_cmn_elem_status_impl_t slsi_common;
400 	DECL_BITFIELD3(
401 	    _reserved1	:6,
402 	    slsi_fail	:1,
403 	    slsi_ident	:1);
404 	uint8_t _reserved2;
405 	DECL_BITFIELD2(
406 	    slsi_unlocked	:1,
407 	    _reserved3		:7);
408 } ses2_lock_status_impl_t;
409 
410 /*
411  * SES-2 Audible Alarm element for control-type diagnostic pages (T78).
412  */
413 typedef struct ses2_alarm_ctl_impl {
414 	ses2_cmn_elem_ctl_impl_t saci_common;
415 	DECL_BITFIELD3(
416 	    _reserved1		:6,
417 	    saci_rqst_fail	:1,
418 	    saci_rqst_ident	:1);
419 	uint8_t _reserved2;
420 	DECL_BITFIELD8(
421 	    saci_unrecov	:1,
422 	    saci_crit		:1,
423 	    saci_noncrit	:1,
424 	    saci_info		:1,
425 	    saci_set_remind	:1,
426 	    _reserved3		:1,
427 	    saci_set_mute	:1,
428 	    _reserved4		:1);
429 } ses2_alarm_ctl_impl_t;
430 
431 /*
432  * SES-2 Audible Alarm element for status-type diagnostic pages
433  * (Table 79, 7.3.8)
434  */
435 typedef struct ses2_alarm_status_impl {
436 	ses2_cmn_elem_status_impl_t sasi_common;
437 	DECL_BITFIELD3(
438 	    _reserved1	:6,
439 	    sasi_fail	:1,
440 	    sasi_ident	:1);
441 	uint8_t _reserved2;
442 	DECL_BITFIELD8(
443 	    sasi_unrecov	:1,
444 	    sasi_crit		:1,
445 	    sasi_noncrit	:1,
446 	    sasi_info		:1,
447 	    sasi_remind		:1,
448 	    _reserved3		:1,
449 	    sasi_muted		:1,
450 	    sasi_rqst_mute	:1);
451 } ses2_alarm_status_impl_t;
452 
453 /*
454  * SES-2 Enclosure Services Controller Electronics element for control-type
455  * diagnostic pages (Table 80, 7.3.9).
456  */
457 typedef struct ses2_controller_ctl_impl {
458 	ses2_cmn_elem_ctl_impl_t scci_common;
459 	DECL_BITFIELD3(
460 	    _reserved1		:6,
461 	    scci_rqst_fail	:1,
462 	    scci_rqst_ident	:1);
463 	DECL_BITFIELD2(
464 	    scci_select_element	:1,
465 	    _reserved2		:7);
466 	uint8_t _reserved3;
467 } ses2_controller_ctl_impl_t;
468 
469 /*
470  * SES-2 Enclosure Services Controller Electronics element for status-type
471  * diagnostic pages (Table 81, 7.3.9),
472  */
473 typedef struct ses2_controller_status_impl {
474 	ses2_cmn_elem_status_impl_t scsi_common;
475 	DECL_BITFIELD3(
476 	    _reserved1	:6,
477 	    scsi_fail	:1,
478 	    scsi_ident	:1);
479 	DECL_BITFIELD2(
480 	    scsi_report	:1,
481 	    _reserved2	:7);
482 	DECL_BITFIELD2(
483 	    _reserved3		:7,
484 	    scsi_hot_swap	:1);
485 } ses2_controller_status_impl_t;
486 
487 /*
488  * SES-2 SCC Controller Electronics element for control-type diagnostic pages
489  * (Table 82, 7.3.10).
490  */
491 typedef struct ses2_scc_ctl_impl {
492 	ses2_cmn_elem_ctl_impl_t ssci_common;
493 	DECL_BITFIELD3(
494 	    _reserved1		:6,
495 	    ssci_rqst_fail	:1,
496 	    ssci_rqst_ident	:1);
497 	uint8_t _reserved2[2];
498 } ses2_scc_ctl_impl_t;
499 
500 /*
501  * SES-2 SCC Controller Electronics element for status-type diagnostic pages
502  * (Table 83, 7.3.10)
503  */
504 typedef struct ses2_scc_status_impl {
505 	ses2_cmn_elem_status_impl_t sss_common;
506 	DECL_BITFIELD3(
507 	    _reserved1	:6,
508 	    sss_fail	:1,
509 	    sss_ident	:1);
510 	DECL_BITFIELD2(
511 	    sss_report	:1,
512 	    _reserved2	:7);
513 	uint8_t _reserved3;
514 } ses2_scc_status_impl_t;
515 
516 /*
517  * SES-2 Nonvolatile Cache element for control-type diagnostic pages
518  * (Table 84, 7.3.11).
519  */
520 typedef struct ses2_nvcache_ctl_impl {
521 	ses2_cmn_elem_ctl_impl_t snci_common;
522 	DECL_BITFIELD3(
523 	    _reserved1		:6,
524 	    snci_rqst_fail	:1,
525 	    snci_rqst_ident	:1);
526 	uint8_t _reserved2[2];
527 } ses2_nvcache_ctl_impl_t;
528 
529 /*
530  * SES-2 Nonvolatile Cache element for status-type diagnostic pages (Table 85,
531  * 7.3.11)
532  */
533 typedef struct ses2_nvcache_status_impl {
534 	ses2_cmn_elem_status_impl_t snsi_common;
535 	DECL_BITFIELD4(
536 	    snsi_size_multiplier	:2,
537 	    _reserved1			:4,
538 	    snsi_fail			:1,
539 	    snsi_ident			:1);
540 	uint16_t snsi_nvcache_size;
541 } ses2_nvcache_status_impl_t;
542 
543 /*
544  * Ibid., Table 86 defines the size multipliers as follows:
545  *
546  * 00b	- bytes
547  * 01b	- 1<<10 bytes
548  * 10b	- 1<<20 bytes
549  * 11b	- 1<<30 bytes
550  *
551  * We will calculate the actual size in bytes by doing
552  *
553  * nvcache_size << (SES2_NVCACHE_SHIFT * multiplier)
554  */
555 #define	SES2_NVCACHE_SHIFT	10
556 #define	SES2_NVCACHE_SIZE(nsip)	\
557 	((uint64_t)SCSI_READ16(&(nsip)->snsi_nvcache_size) << \
558 	    (SES2_NVCACHE_SHIFT * (nsip)->snsi_size_multiplier))
559 
560 /*
561  * SES-2 Invalid Operation Reason element for status-type diagnostic pages
562  * (Table 88, 7.3.12)
563  */
564 typedef struct ses2_invop_reason_status_impl {
565 	ses2_cmn_elem_status_impl_t sirsi_common;
566 	DECL_BITFIELD2(
567 	    sirsi_priv_ms6	:6,
568 	    sirsi_invop_type	:2);
569 	uint8_t sirsi_priv[2];
570 } ses2_invop_reason_status_impl_t;
571 
572 /*
573  * Ibid., Invop Type values (Table 89)
574  */
575 typedef enum ses2_invop_type {
576 	SES2_INVOP_SEND_PAGE_CODE = 0x0,
577 	SES2_INVOP_SEND_PAGE_FORMAT = 0x1,
578 	SES2_INVOP_VENDOR_SPECIFIC = 0x3
579 } ses2_invop_type_t;
580 
581 /*
582  * Ibid., Invalid Operation Reason element for status-type diagnostic pages
583  * with Invop Type of 00b (Table 90)
584  */
585 typedef struct ses2_invop_code_status_impl {
586 	ses2_cmn_elem_status_impl_t sicsi_common;
587 	DECL_BITFIELD3(
588 	    sicsi_page_not_supported	:1,
589 	    _reserved1			:5,
590 	    sicsi_invop_type		:2);
591 	uint8_t _reserved2[2];
592 } ses2_invop_code_status_impl_t;
593 
594 /*
595  * Ibid., Invalid Operation Reason element for status-type diagnostic pages
596  * with Invop Type of 01b (Table 91)
597  */
598 typedef struct ses2_invop_format_status_impl {
599 	ses2_cmn_elem_status_impl_t sifsi_common;
600 	DECL_BITFIELD3(
601 	    sifsi_bit_number	:3,
602 	    _reserved1		:3,
603 	    sifsi_invop_type	:2);
604 	uint16_t sifsi_byte_offset[2];
605 } ses2_invop_format_status_impl_t;
606 
607 /*
608  * SES-2 Uninterruptible Power Supply element for control-type diagnostic
609  * pages (Table 93, 7.3.13)
610  */
611 typedef struct ses2_ups_ctl_impl {
612 	ses2_cmn_elem_ctl_impl_t suci_common;
613 	uint8_t _reserved1[2];
614 	DECL_BITFIELD3(
615 	    _reserved2		:6,
616 	    suci_rqst_fail	:1,
617 	    suci_rqst_ident	:1);
618 } ses2_ups_ctl_impl_t;
619 
620 /*
621  * SES-2 Uninterruptible Power Supply element for status-type diagnostic pages
622  * (Table 94, 7.3.13)
623  */
624 typedef struct ses2_ups_status_impl {
625 	ses2_cmn_elem_status_impl_t susi_common;
626 	uint8_t susi_battery_status;	/* Time remaining in minutes */
627 	DECL_BITFIELD8(
628 	    susi_intf_fail	:1,
629 	    susi_warn		:1,
630 	    susi_ups_fail	:1,
631 	    susi_dc_fail	:1,
632 	    susi_ac_fail	:1,
633 	    susi_ac_qual	:1,
634 	    susi_ac_hi		:1,
635 	    susi_ac_lo		:1);
636 	DECL_BITFIELD5(
637 	    susi_bpf		:1,
638 	    susi_batt_fail	:1,
639 	    _reserved1		:4,
640 	    susi_fail		:1,
641 	    susi_ident		:1);
642 } ses2_ups_status_impl_t;
643 
644 /*
645  * SES-2 Display element for control-type diagnostic pages (Table 95, 7.3.14)
646  */
647 typedef struct ses2_display_ctl_impl {
648 	ses2_cmn_elem_ctl_impl_t sdci_common;
649 	DECL_BITFIELD4(
650 	    sdci_display_mode	:2,
651 	    _reserved1		:4,
652 	    sdci_rqst_fail	:1,
653 	    sdci_rqst_ident	:1);
654 	uint16_t sdci_display_character;
655 } ses2_display_ctl_impl_t;
656 
657 /*
658  * SES-2 Display element for status-type diagnostic pages (Table 97, 7.3.14)
659  */
660 typedef struct ses2_display_status_impl {
661 	ses2_cmn_elem_status_impl_t sdsi_common;
662 	DECL_BITFIELD4(
663 	    sdsi_display_mode_status	:2,
664 	    _reserved1			:3,
665 	    sdsi_fail			:1,
666 	    sdsi_ident			:1);
667 	uint16_t sdsi_display_character_status;
668 } ses2_display_status_impl_t;
669 
670 /*
671  * SES-2 Key Pad Entry element for control-type diagnostic pages (Table 99).
672  */
673 typedef struct ses2_keypad_ctl_impl {
674 	ses2_cmn_elem_ctl_impl_t skci_common;
675 	DECL_BITFIELD3(
676 	    _reserved1		:6,
677 	    skci_rqst_fail	:1,
678 	    skci_rqst_ident	:1);
679 	uint8_t _reserved2[2];
680 } ses2_keypad_ctl_impl_t;
681 
682 /*
683  * SES-2 Key Pad Entry element for status-type diagnostic pages (Table 100,
684  * 7.3.15)
685  */
686 typedef struct ses2_keypad_status_impl {
687 	ses2_cmn_elem_status_impl_t sksi_common;
688 	DECL_BITFIELD3(
689 	    _reserved1	:6,
690 	    sksi_fail	:1,
691 	    sksi_ident	:1);
692 	uint8_t _reserved2[2];
693 } ses2_keypad_status_impl_t;
694 
695 /*
696  * SES-2 Enclosure element for control-type diagnostic pages (Table 101).
697  */
698 typedef struct ses2_enclosure_ctl_impl {
699 	ses2_cmn_elem_ctl_impl_t seci_common;
700 	DECL_BITFIELD2(
701 	    _reserved1		:7,
702 	    seci_rqst_ident	:1);
703 	DECL_BITFIELD2(
704 	    seci_power_cycle_delay	:6,
705 	    seci_power_cycle_request	:2);
706 	DECL_BITFIELD3(
707 	    seci_request_warning	:1,
708 	    seci_request_failure	:1,
709 	    seci_power_off_duration	:6);
710 } ses2_enclosure_ctl_impl_t;
711 
712 /*
713  * SES-2 Enclosure element for status-type diagnostic pages (Table 101, 7.3.16)
714  */
715 typedef struct ses2_enclosure_status_impl {
716 	ses2_cmn_elem_status_impl_t sesi_common;
717 	DECL_BITFIELD2(
718 	    _reserved1	:7,
719 	    sesi_ident	:1);
720 	DECL_BITFIELD3(
721 	    sesi_warning_indication	:1,
722 	    sesi_failure_indication	:1,
723 	    sesi_power_delay		:6);
724 	DECL_BITFIELD3(
725 	    sesi_warning_requested	:1,
726 	    sesi_failure_requested	:1,
727 	    sesi_power_duration		:6);
728 } ses2_enclosure_status_impl_t;
729 
730 /*
731  * SES-2 SCSI Port/Transceiver element for control-type diagnostic pages (T103)
732  */
733 typedef struct ses2_port_ctl_impl {
734 	ses2_cmn_elem_ctl_impl_t spci_common;
735 	DECL_BITFIELD3(
736 	    _reserved1		:6,
737 	    spci_rqst_fail	:1,
738 	    spci_rqst_ident	:1);
739 	uint8_t _reserved2;
740 	DECL_BITFIELD3(
741 	    _reserved3		:4,
742 	    spci_disable	:1,
743 	    _reserved4		:3);
744 } ses2_port_ctl_impl_t;
745 
746 /*
747  * SES-2 SCSI Port/Transceiver element for status-type diagnostic pages
748  * (Table 104, 7.3.17)
749  */
750 typedef struct ses2_port_status_impl {
751 	ses2_cmn_elem_status_impl_t spsi_common;
752 	DECL_BITFIELD3(
753 	    _reserved1	:6,
754 	    spsi_fail	:1,
755 	    spsi_ident	:1);
756 	DECL_BITFIELD2(
757 	    spsi_report	:1,
758 	    _reserved2	:7);
759 	DECL_BITFIELD5(
760 	    spsi_xmit_fail	:1,
761 	    spsi_lol		:1,
762 	    _reserved3		:2,
763 	    spsi_disabled	:1,
764 	    _reserved4		:3);
765 } ses2_port_status_impl_t;
766 
767 /*
768  * SES-2 Language element for control-type diagnostic pages (T105)
769  */
770 typedef struct ses2_lang_ctl_impl {
771 	ses2_cmn_elem_ctl_impl_t slci_common;
772 	DECL_BITFIELD2(
773 	    _reserved1		:7,
774 	    slci_rqst_ident	:1);
775 	uint16_t slci_language_code;
776 } ses2_lang_ctl_impl_t;
777 
778 /*
779  * SES-2 Language element for status-type diagnostic pages (Table 105, 7.3.18)
780  */
781 typedef struct ses2_lang_status_impl {
782 	ses2_cmn_elem_status_impl_t slsi_common;
783 	DECL_BITFIELD2(
784 	    _reserved1	:7,
785 	    slsi_ident	:1);
786 	uint16_t slsi_language_code;
787 } ses2_lang_status_impl_t;
788 
789 /*
790  * SES-2 Communication Port element for control-type diagnostic pages
791  * (Table 107, 7.3.19).
792  */
793 typedef struct ses2_comm_ctl_impl {
794 	ses2_cmn_elem_ctl_impl_t scci_common;
795 	DECL_BITFIELD3(
796 	    _reserved1		:6,
797 	    scci_rqst_fail	:1,
798 	    scci_rqst_ident	:1);
799 	uint8_t _reserved2;
800 	DECL_BITFIELD2(
801 	    scci_disable	:1,
802 	    _reserved3		:7);
803 } ses2_comm_ctl_impl_t;
804 
805 /*
806  * SES-2 Communication Port element for status-type diagnostic pages
807  * (Table 108, 7.3.19)
808  */
809 typedef struct ses2_comm_status_impl {
810 	ses2_cmn_elem_status_impl_t scsi_common;
811 	DECL_BITFIELD3(
812 	    _reserved1	:6,
813 	    scsi_fail	:1,
814 	    scsi_ident	:1);
815 	uint8_t _reserved2;
816 	DECL_BITFIELD2(
817 	    scsi_disabled	:1,
818 	    _reserved3		:7);
819 } ses2_comm_status_impl_t;
820 
821 /*
822  * SES-2 Voltage Sensor element for control-type diagnostic pages
823  * (Table 109, 7.3.20).
824  */
825 typedef struct ses2_voltage_ctl_impl {
826 	ses2_cmn_elem_ctl_impl_t svci_common;
827 	DECL_BITFIELD3(
828 	    _reserved1		:6,
829 	    svci_rqst_fail	:1,
830 	    svci_rqst_ident	:1);
831 	uint8_t _reserved2[2];
832 } ses2_voltage_ctl_impl_t;
833 
834 /*
835  * SES-2 Voltage Sensor element for status-type diagnostic pages
836  * (Table 110, 7.3.20).
837  */
838 typedef struct ses2_voltage_status_impl {
839 	ses2_cmn_elem_status_impl_t svsi_common;
840 	DECL_BITFIELD7(
841 	    svsi_crit_under	:1,
842 	    svsi_crit_over	:1,
843 	    svsi_warn_under	:1,
844 	    svsi_warn_over	:1,
845 	    _reserved1		:2,
846 	    svsi_fail		:1,
847 	    svsi_ident		:1);
848 	uint16_t svsi_voltage;
849 } ses2_voltage_status_impl_t;
850 
851 /*
852  * Ibid. defines the svsi_voltage field as a 16-bit signed 2's complement
853  * integer, represented in units of 10 mV.  AC voltages are RMS.
854  */
855 #define	SES2_VOLTAGE_MULTIPLIER	(0.01)
856 #define	SES2_VOLTAGE(vsip)	\
857 	(SCSI_READ16(&(vsip)->svsi_voltage) * SES2_VOLTAGE_MULTIPLIER)
858 
859 /*
860  * SES-2 Current Sensor element for control-type diagnostic pages
861  * (Table 111, 7.3.21).
862  */
863 typedef struct ses2_current_ctl_impl {
864 	ses2_cmn_elem_ctl_impl_t scci_common;
865 	DECL_BITFIELD3(
866 	    _reserved1		:6,
867 	    scci_rqst_fail	:1,
868 	    scci_rqst_ident	:1);
869 	uint8_t _reserved2[2];
870 } ses2_current_ctl_impl_t;
871 
872 /*
873  * SES-2 Current Sensor element for status-type diagnostic pages
874  * (Table 112, 7.3.21)
875  */
876 typedef struct ses2_current_status_impl {
877 	ses2_cmn_elem_status_impl_t scsi_common;
878 	DECL_BITFIELD7(
879 	    _reserved1		:1,
880 	    scsi_crit_over	:1,
881 	    _reserved2		:1,
882 	    scsi_warn_over	:1,
883 	    _reserved3		:2,
884 	    scsi_fail		:1,
885 	    scsi_ident		:1);
886 	uint16_t scsi_current;
887 } ses2_current_status_impl_t;
888 
889 /*
890  * Ibid. defines the scsi_voltage field in the same way as for voltage above.
891  * Units here are 10 mA.  AC amperages are RMS.
892  */
893 #define	SES2_CURRENT_MULTIPLIER	(0.01)
894 #define	SES2_CURRENT(csip)	\
895 	(SCSI_READ16(&(csip)->scsi_current) * SES2_CURRENT_MULTIPLIER)
896 
897 /*
898  * SES-2 SCSI Target Port element for control-type diagnostic pages
899  * (Table 113, 7.3.22), SCSI Initiator Port element for control-type
900  * diagnostic pages (Table 115, 7.3.23).
901  */
902 typedef struct ses2_itp_ctl_impl {
903 	ses2_cmn_elem_ctl_impl_t sici_common;
904 	DECL_BITFIELD3(
905 	    _reserved1		:6,
906 	    sici_rqst_fail	:1,
907 	    sici_rqst_ident	:1);
908 	uint8_t _reserved2;
909 	DECL_BITFIELD2(
910 	    sici_enable	:1,
911 	    _reserved3	:7);
912 } ses2_itp_ctl_impl_t;
913 
914 /*
915  * SES-2 SCSI Target Port element for status-type diagnostic pages (Table 114,
916  * 7.3.22), SCSI Initiator Port element for status-type diagnostic pages
917  * (Table 116, 7.3.23)
918  */
919 typedef struct ses2_itp_status_impl {
920 	ses2_cmn_elem_status_impl_t sisi_common;
921 	DECL_BITFIELD3(
922 	    _reserved1	:6,
923 	    sisi_fail	:1,
924 	    sisi_ident	:1);
925 	DECL_BITFIELD2(
926 	    sisi_report	:1,
927 	    _reserved2	:7);
928 	DECL_BITFIELD2(
929 	    sisi_enabled	:1,
930 	    _reserved3		:7);
931 } ses2_itp_status_impl_t;
932 
933 /*
934  * SES-2 Simple Subenclosure element for control-type diagnostic pages
935  * (Table 117, 7.3.24).
936  */
937 typedef struct ses2_ss_ctl_impl {
938 	ses2_cmn_elem_ctl_impl_t ssci_common;
939 	DECL_BITFIELD3(
940 	    _reserved1		:6,
941 	    ssci_rqst_fail	:1,
942 	    ssci_rqst_ident	:1);
943 	uint8_t _reserved2[2];
944 } ses2_ss_ctl_impl_t;
945 
946 /*
947  * SES-2 Simple Subenclosure element for status-type diagnostic pages
948  * (Table 117, 7.3.24)
949  */
950 typedef struct ses2_ss_status_impl {
951 	ses2_cmn_elem_status_impl_t sss_common;
952 	DECL_BITFIELD3(
953 	    _reserved1	:6,
954 	    sss_fail	:1,
955 	    sss_ident	:1);
956 	uint8_t _reserved2;
957 	uint8_t sss_short_status;
958 } ses2_ss_status_impl_t;
959 
960 /*
961  * SES-2 SAS Expander element for control-type diagnostic pages
962  * (Table 119, 7.3.25).
963  */
964 typedef struct ses2_expander_ctl_impl {
965 	ses2_cmn_elem_ctl_impl_t seci_common;
966 	DECL_BITFIELD3(
967 	    _reserved1		:6,
968 	    seci_rqst_fail	:1,
969 	    seci_rqst_ident	:1);
970 	uint8_t _reserved2[2];
971 } ses2_expander_ctl_impl_t;
972 
973 /*
974  * SES-2 SAS Expander element for status-type diagnostic pages (Table 120,
975  * 7.3.25)
976  */
977 typedef struct ses2_expander_status_impl {
978 	ses2_cmn_elem_status_impl_t sesi_common;
979 	DECL_BITFIELD3(
980 	    _reserved1	:6,
981 	    sesi_fail	:1,
982 	    sesi_ident	:1);
983 	uint8_t _reserved2[2];
984 } ses2_expander_status_impl_t;
985 
986 /*
987  * SES-2 SAS Connector element for control-type diagnostic pages (Table 121,
988  * 7.3.26).
989  */
990 typedef struct ses2_sasconn_ctl_impl {
991 	ses2_cmn_elem_ctl_impl_t ssci_common;
992 	DECL_BITFIELD2(
993 	    _reserved1		:7,
994 	    ssci_rqst_ident	:1);
995 	uint8_t _reserved2;
996 	DECL_BITFIELD3(
997 	    _reserved3		:6,
998 	    ssci_rqst_fail	:1,
999 	    _reserved4		:1);
1000 } ses2_sasconn_ctl_impl_t;
1001 
1002 /*
1003  * SES-2 SAS Connector element for status-type diagnostic pages (Table 122,
1004  * 7.3.26)
1005  */
1006 typedef struct ses2_sasconn_status_impl {
1007 	ses2_cmn_elem_status_impl_t sss_common;
1008 	DECL_BITFIELD2(
1009 	    sss_connector_type	:7,
1010 	    sss_ident		:1);
1011 	uint8_t sss_connector_physical_link;
1012 	DECL_BITFIELD3(
1013 	    _reserved1	:6,
1014 	    sss_fail	:1,
1015 	    _reserved2	:1);
1016 } ses2_sasconn_status_impl_t;
1017 
1018 /*
1019  * SES-2 Enclosure Control diagnostic page (Table 10, 6.1.3)
1020  */
1021 typedef struct ses2_control_page_impl {
1022 	uint8_t scpi_page_code;
1023 	DECL_BITFIELD5(
1024 	    scpi_unrecov	:1,
1025 	    scpi_crit		:1,
1026 	    scpi_noncrit	:1,
1027 	    scpi_info		:1,
1028 	    _reserved1		:4);
1029 	uint16_t scpi_page_length;
1030 	uint32_t scpi_generation_code;
1031 	ses2_elem_ctl_impl_t scpi_data[1];
1032 } ses2_control_page_impl_t;
1033 
1034 /*
1035  * SES-2 Enclosure Status (Table 11, 6.1.4)
1036  */
1037 typedef struct ses2_status_page_impl {
1038 	uint8_t sspi_page_code;
1039 	DECL_BITFIELD6(
1040 	    sspi_unrecov	:1,
1041 	    sspi_crit		:1,
1042 	    sspi_noncrit	:1,
1043 	    sspi_info		:1,
1044 	    sspi_invop		:1,
1045 	    _reserved1		:3);
1046 	uint16_t sspi_page_length;
1047 	uint32_t sspi_generation_code;
1048 	uint8_t sspi_data[1];
1049 } ses2_status_page_impl_t;
1050 
1051 /*
1052  * SES-2 Help Text diagnostic page (Table 13, 6.1.5).
1053  */
1054 typedef struct ses2_help_page_impl {
1055 	uint8_t shpi_page_code;
1056 	uint8_t _reserved1;
1057 	uint16_t shpi_page_length;
1058 	char shpi_help_text[1];
1059 } ses2_help_page_impl_t;
1060 
1061 /*
1062  * SES-2 String Out diagnostic page (Table 14, 6.1.6).
1063  */
1064 typedef struct ses2_string_out_page_impl {
1065 	uint8_t ssopi_page_code;
1066 	uint8_t _reserved1;
1067 	uint16_t ssopi_page_length;
1068 	uint8_t ssopi_data[1];
1069 } ses2_string_out_page_impl_t;
1070 
1071 /*
1072  * SES-2 String In diagnostic page (Table 15, 6.1.7).
1073  */
1074 typedef struct ses2_string_in_page_impl {
1075 	uint8_t ssipi_page_code;
1076 	uint8_t _reserved1;
1077 	uint16_t ssipi_page_length;
1078 	uint8_t ssipi_data[1];
1079 } ses2_string_in_page_impl_t;
1080 
1081 /*
1082  * SES-2 Threshold fields - (Table 17, 6.1.8), (Table 19, 6.1.9).
1083  */
1084 typedef struct ses2_threshold_impl {
1085 	uint8_t sti_high_crit;
1086 	uint8_t sti_high_warn;
1087 	uint8_t sti_low_warn;
1088 	uint8_t sti_low_crit;
1089 } ses2_threshold_impl_t;
1090 
1091 /*
1092  * SES-2 Threshold Out diagnostic page (Table 16, 6.1.8).
1093  */
1094 typedef struct ses2_threshold_out_page_impl {
1095 	uint8_t stopi_page_code;
1096 	uint8_t _reserved1;
1097 	uint16_t stopi_page_length;
1098 	uint32_t stopi_generation_code;
1099 	ses2_threshold_impl_t stopi_thresholds[1];
1100 } ses2_threshold_out_page_impl_t;
1101 
1102 /*
1103  * SES-2 Threshold In diagnostic page (Table 18, 6.1.9).
1104  */
1105 typedef struct ses2_threshold_in_page_impl {
1106 	uint8_t stipi_page_code;
1107 	DECL_BITFIELD3(
1108 	    _reserved1	:4,
1109 	    stipi_invop	:1,
1110 	    _reserved2	:3);
1111 	uint16_t stipi_page_length;
1112 	uint32_t stipi_generation_code;
1113 	ses2_threshold_impl_t stipi_thresholds[1];
1114 } ses2_threshold_in_page_impl_t;
1115 
1116 /*
1117  * SES-2 Element Descriptor diagnostic page (Table 20, 6.1.10).
1118  */
1119 typedef struct ses2_elem_desc_page_impl {
1120 	uint8_t sedpi_page_code;
1121 	uint8_t _reserved1;
1122 	uint16_t sedpi_page_length;
1123 	uint32_t sedpi_generation_code;
1124 	uint8_t sedpi_data[1];
1125 } ses2_elem_desc_page_impl_t;
1126 
1127 /*
1128  * SES-2 Overall/element descriptor format (Table 22, 6.1.10).
1129  */
1130 typedef struct ses2_elem_descriptor_impl {
1131 	uint8_t _reserved1[2];
1132 	uint16_t sedi_descriptor_length;
1133 	char sedi_descriptor[1];
1134 } ses2_elem_descriptor_impl_t;
1135 
1136 /*
1137  * SES-2 Short Enclosure Status diagnostic page (Table 23, 6.1.11).
1138  */
1139 typedef struct ses2_short_status_page_impl {
1140 	uint8_t ssspi_page_code;
1141 	uint8_t ssspi_short_status;
1142 	uint16_t ssspi_page_length;
1143 } ses2_short_status_page_impl_t;
1144 
1145 /*
1146  * SES-2 Enclosure Busy diagnostic page (Table 24, 6.1.12).
1147  */
1148 typedef struct ses2_enclosure_busy_page_impl {
1149 	uint8_t sebpi_page_code;
1150 	DECL_BITFIELD2(
1151 	    sebpi_busy		:1,
1152 	    sebpi_vs_1_1	:7);
1153 	uint16_t sebpi_page_length;
1154 } ses2_enclosure_busy_page_impl_t;
1155 
1156 /*
1157  * SES-2 Additional Element Status diagnostic page (Table 25, 6.1.13).
1158  */
1159 typedef struct ses2_aes_page_impl {
1160 	uint8_t sapi_page_code;
1161 	uint8_t _reserved1;
1162 	uint16_t sapi_page_length;
1163 	uint32_t sapi_generation_code;
1164 	uint8_t sapi_data[1];
1165 } ses2_aes_page_impl_t;
1166 
1167 /*
1168  * SES-2 Additional Element Status descriptor (EIP == 1) (Table 26, 6.1.13).
1169  * Updated with EIIOE for Table 32 from SES-3, 6.1.13.
1170  * Note that we think later revs of SES-3 probably widen the EIIOE to 2 bits,
1171  * waiting for final document to be sure.
1172  */
1173 typedef struct ses2_aes_descr_eip_impl {
1174 	DECL_BITFIELD4(
1175 	    sadei_protocol_identifier	:4,
1176 	    sadei_eip			:1,
1177 	    _reserved1			:2,
1178 	    sadei_invalid		:1);
1179 	uint8_t sadei_length;
1180 	DECL_BITFIELD2(
1181 	    sadei_eiioe			:2,
1182 	    _reserved2			:6);
1183 	uint8_t sadei_element_index;
1184 	uint8_t sadei_protocol_specific[1];
1185 } ses2_aes_descr_eip_impl_t;
1186 
1187 /*
1188  * SES-2 Additional Element Status descriptor (EIP == 0) (Table 27, 6.1.13).
1189  */
1190 typedef struct ses2_aes_descr_impl {
1191 	DECL_BITFIELD4(
1192 	    sadei_protocol_identifier	:4,
1193 	    sadei_eip			:1,
1194 	    _reserved1			:2,
1195 	    sadei_invalid		:1);
1196 	uint8_t sadei_length;
1197 	uint8_t sadei_protocol_specific[1];
1198 } ses2_aes_descr_impl_t;
1199 
1200 /*
1201  * SES-2 Port descriptor (Table 30, 6.1.13.2).
1202  */
1203 typedef struct ses2_aes_port_descr_impl {
1204 	uint8_t sapdi_port_loop_position;
1205 	uint8_t _reserved1[3];
1206 	uint8_t sapdi_port_requested_hard_address;
1207 	uint8_t sapdi_n_port_identifier[3];
1208 	uint64_t sapdi_n_port_name;
1209 } ses2_aes_port_descr_impl_t;
1210 
1211 /*
1212  * SES-2 Additional Element Status descriptor for FC (Table 28, 6.1.13.2).
1213  */
1214 typedef struct ses2_aes_descr_fc_eip_impl {
1215 	uint8_t sadfi_n_ports;
1216 	uint8_t _reserved1[2];
1217 	uint8_t sadfi_bay_number;
1218 	uint64_t sadfi_node_name;
1219 	ses2_aes_port_descr_impl_t sadfi_ports[1];
1220 } ses2_aes_descr_fc_eip_impl_t;
1221 
1222 /*
1223  * SES-2 Additional Element Status descriptor for FC (EIP == 0)
1224  * (Table 29, 6.1.13.2).
1225  */
1226 typedef struct ses2_aes_descr_fc_impl {
1227 	uint8_t sadfi_n_ports;
1228 	uint8_t _reserved1;
1229 	uint64_t sadfi_node_name;
1230 	ses2_aes_port_descr_impl_t sadfi_ports[1];
1231 } ses2_aes_descr_fc_impl_t;
1232 
1233 /*
1234  * SES-2 Additional Element Status descriptor for SAS (Table 31, 6.1.13.3).
1235  */
1236 typedef struct ses2_aes_descr_sas_impl {
1237 	uint8_t _specific1;
1238 	DECL_BITFIELD2(
1239 	    _specific2			:6,
1240 	    sadsi_descriptor_type	:2);
1241 	uint8_t _specific3[1];
1242 } ses2_aes_descr_sas_impl_t;
1243 
1244 typedef enum ses2_aes_descr_sas_type {
1245 	SES2_AESD_SAS_DEVICE = 0,
1246 	SES2_AESD_SAS_OTHER = 1
1247 } ses2_aes_descr_sas_type_t;
1248 
1249 typedef struct ses2_aes_phy0_descr_impl {
1250 	DECL_BITFIELD3(
1251 	    _reserved1		:4,
1252 	    sapdi_device_type	:3,
1253 	    _reserved2		:1);
1254 	uint8_t _reserved3;
1255 	DECL_BITFIELD5(
1256 	    _reserved4			:1,
1257 	    sapdi_smp_initiator_port	:1,
1258 	    sapdi_stp_initiator_port	:1,
1259 	    sapdi_ssp_initiator_port	:1,
1260 	    _reserved5			:4);
1261 	DECL_BITFIELD6(
1262 	    sapdi_sata_device		:1,
1263 	    sapdi_smp_target_port	:1,
1264 	    sapdi_stp_target_port	:1,
1265 	    sapdi_ssp_target_port	:1,
1266 	    _reserved6			:3,
1267 	    sapdi_sata_port_selector	:1);
1268 	uint64_t sapdi_attached_sas_address;
1269 	uint64_t sapdi_sas_address;
1270 	uint8_t sapdi_phy_identifier;
1271 	uint8_t _reserved7[7];
1272 } ses2_aes_phy0_descr_impl_t;
1273 
1274 typedef struct ses2_aes_descr_sas0_eip_impl {
1275 	uint8_t sadsi_n_phy_descriptors;
1276 	DECL_BITFIELD3(
1277 	    sadsi_not_all_phys		:1,
1278 	    _reserved1			:5,
1279 	    sadsi_descriptor_type	:2);
1280 	uint8_t _reserved2;
1281 	uint8_t sadsi_bay_number;
1282 	ses2_aes_phy0_descr_impl_t sadsi_phys[1];
1283 } ses2_aes_descr_sas0_eip_impl_t;
1284 
1285 typedef struct ses2_aes_descr_sas0_impl {
1286 	uint8_t sadsi_n_phy_descriptors;
1287 	DECL_BITFIELD3(
1288 	    sadsi_not_all_phys		:1,
1289 	    _reserved1			:5,
1290 	    sadsi_descriptor_type	:2);
1291 	ses2_aes_phy0_descr_impl_t sadsi_phys[1];
1292 } ses2_aes_descr_sas0_impl_t;
1293 
1294 /*
1295  * SES-2 Additional Element Status for SAS Expander elements
1296  * (Table 36, 6.1.13.3.3).
1297  */
1298 typedef struct ses2_aes_exp_phy_descr_impl {
1299 	uint8_t saepdi_connector_element_index;
1300 	uint8_t saepdi_other_element_index;
1301 } ses2_aes_exp_phy_descr_impl_t;
1302 
1303 typedef struct ses2_aes_descr_exp_impl {
1304 	uint8_t sadei_n_exp_phy_descriptors;
1305 	DECL_BITFIELD2(
1306 	    _reserved1			:6,
1307 	    sadei_descriptor_type	:2);
1308 	uint8_t _reserved2[2];
1309 	uint64_t sadei_sas_address;
1310 	ses2_aes_exp_phy_descr_impl_t sadei_phys[1];
1311 } ses2_aes_descr_exp_impl_t;
1312 
1313 /*
1314  * SES-2 Additional Element Status for SCSI Initiator/Target Port and
1315  * Enclosure Services Controller Electronics elements (Table 38, 6.1.13.3.4).
1316  */
1317 typedef struct ses2_aes_phy1_descr_impl {
1318 	uint8_t sapdi_phy_identifier;
1319 	uint8_t _reserved1;
1320 	uint8_t sapdi_connector_element_index;
1321 	uint8_t sapdi_other_element_index;
1322 	uint64_t sapdi_sas_address;
1323 } ses2_aes_phy1_descr_impl_t;
1324 
1325 typedef struct ses2_aes_descr_sas1_impl {
1326 	uint8_t sadsi_n_phy_descriptors;
1327 	DECL_BITFIELD2(
1328 	    _reserved1			:6,
1329 	    sadsi_descriptor_type	:2);
1330 	uint8_t _reserved2[2];
1331 	ses2_aes_phy1_descr_impl_t sadsi_phys[1];
1332 } ses2_aes_descr_sas1_impl_t;
1333 
1334 /*
1335  * SES-2 Subenclosure Help Text diagnostic page (Table 40, 6.1.14).
1336  */
1337 typedef struct ses2_subhelp_page_impl {
1338 	uint8_t sspi_page_code;
1339 	uint8_t sspi_n_subenclosures;
1340 	uint16_t sspi_page_length;
1341 	uint32_t sspi_generation_code;
1342 	uint8_t sspi_data[1];
1343 } ses2_subhelp_page_impl_t;
1344 
1345 /*
1346  * SES-2 Subenclosure help text format (Table 41, 6.1.14).
1347  */
1348 typedef struct ses2_subhelp_text_impl {
1349 	uint8_t _reserved1;
1350 	uint8_t ssti_subenclosure_identifier;
1351 	uint16_t ssti_subenclosure_help_text_length;
1352 	char ssti_subenclosure_help_text[1];
1353 } ses2_subhelp_text_impl_t;
1354 
1355 #define	SES2_SUBHELP_LEN(stip)	\
1356 	(SCSI_READ16(&(stip)->ssti_subenclosure_help_text_length) + \
1357 	    offsetof(ses2_subhelp_text_impl_t, ssti_subenclosure_help_text[0]))
1358 /*
1359  * SES-2 Subenclosure String Out diagnostic page (Table 42, 6.1.15).
1360  */
1361 typedef struct ses2_substring_out_page_impl {
1362 	uint8_t ssopi_page_code;
1363 	uint8_t ssopi_subenclosure_identifier;
1364 	uint16_t ssopi_page_length;
1365 	uint32_t ssopi_generation_code;
1366 	uint8_t ssopi_data[1];
1367 } ses2_substring_out_page_impl_t;
1368 
1369 /*
1370  * SES-2 Subenclosure String In diagnostic page (Table 43, 6.1.16).
1371  */
1372 typedef struct ses2_substring_in_page_impl {
1373 	uint8_t ssipi_page_code;
1374 	uint8_t ssipi_n_subenclosures;
1375 	uint16_t ssipi_page_length;
1376 	uint32_t ssipi_generation_code;
1377 	uint8_t ssipi_data[1];
1378 } ses2_substring_in_page_impl_t;
1379 
1380 /*
1381  * SES-2 Subenclosure string in data format (Table 44, 6.1.16).
1382  */
1383 typedef struct ses2_substring_in_data_impl {
1384 	uint8_t _reserved1;
1385 	uint8_t ssidi_subenclosure_identifier;
1386 	uint16_t ssidi_substring_data_length;
1387 	uint8_t ssidi_data[1];
1388 } ses2_substring_in_data_impl_t;
1389 
1390 #define	SES2_SUBSTR_LEN(sdip)	\
1391 	(SCSI_READ16(&(sdip)->ssidi_substring_data_length) + \
1392 	    offsetof(ses2_substring_in_data_impl_t, ssidi_data[0]))
1393 
1394 /*
1395  * SES-2 Supported SES Diagnostic Pages diagnostic page (Table 45, 6.1.17).
1396  */
1397 typedef struct ses2_supported_ses_diag_page_impl {
1398 	uint8_t sssdpi_page_code;
1399 	uint8_t _reserved1;
1400 	uint16_t sssdpi_page_length;
1401 	uint8_t sssdpi_pages[1];
1402 } ses2_supported_ses_diag_page_impl_t;
1403 
1404 /*
1405  * SES-2 Download Microcode Control diagnostic page (Table 46, 6.1.18).
1406  */
1407 typedef struct ses2_ucode_ctl_page_impl {
1408 	uint8_t sucpi_page_code;
1409 	uint8_t sucpi_subenclosure_identifier;
1410 	uint16_t sucpi_page_length;
1411 	uint32_t sucpi_generation_code;
1412 	uint8_t sucpi_dl_ucode_mode;
1413 	uint8_t _reserved1[2];
1414 	uint8_t sucpi_buffer_id;
1415 	uint32_t sucpi_buffer_offset;
1416 	uint32_t sucpi_ucode_image_length;
1417 	uint32_t sucpi_ucode_data_length;
1418 	uint8_t sucpi_ucode_data[1];
1419 } ses2_ucode_ctl_page_impl_t;
1420 
1421 /*
1422  * SES-2 Download Microcode Status diagnostic page (Table 48-49, 6.1.19).
1423  */
1424 typedef struct ses2_ucode_status_descr_impl {
1425 	uint8_t _reserved1;
1426 	uint8_t susdi_subenclosure_identifier;
1427 	uint8_t susdi_subenclosure_dl_status;
1428 	uint8_t susdi_subenclosure_dl_addl_status;
1429 	uint32_t susdi_subenclosure_dl_max_size;
1430 	uint8_t _reserved2[3];
1431 	uint8_t susdi_subenclosure_dl_buffer_id;
1432 	uint32_t susdi_subenclosure_dl_buffer_offset;
1433 } ses2_ucode_status_descr_impl_t;
1434 
1435 typedef struct ses2_ucode_status_page_impl {
1436 	uint8_t suspi_page_code;
1437 	uint8_t suspi_n_subenclosures;
1438 	uint16_t suspi_page_length;
1439 	uint32_t suspi_generation_code;
1440 	ses2_ucode_status_descr_impl_t suspi_descriptors[1];
1441 } ses2_ucode_status_page_impl_t;
1442 
1443 /*
1444  * SES-2 Subenclosure Nickname Control diagnostic page (Table 51, 6.1.20).
1445  */
1446 typedef struct ses2_subnick_ctl_page_impl {
1447 	uint8_t sscpi_page_code;
1448 	uint8_t sspci_subenclosure_identifier;
1449 	uint16_t sspci_page_length;
1450 	uint32_t sspci_generation_code;
1451 	char sspci_subenclosure_nickname[32];
1452 } ses2_subnick_ctl_page_impl_t;
1453 
1454 /*
1455  * SES-2 Subenclosure Nickname Status diagnostic page (Table 52-53, 6.1.21).
1456  */
1457 typedef struct ses2_subnick_descr_impl {
1458 	uint8_t _reserved1;
1459 	uint8_t ssdi_subenclosure_identifier;
1460 	uint8_t ssdi_subenclosure_nick_status;
1461 	uint8_t ssdi_subenclosure_nick_addl_status;
1462 	uint8_t _reserved2[2];
1463 	uint16_t ssdi_subenclosure_nick_lang_code;
1464 	char ssdi_subenclosure_nickname[32];
1465 } ses2_subnick_descr_impl_t;
1466 
1467 typedef struct ses2_subnick_status_page_impl {
1468 	uint8_t sspsi_page_code;
1469 	uint8_t sspci_n_subenclosures;
1470 	uint16_t sspci_page_length;
1471 	uint32_t sspci_generation_code;
1472 	ses2_subnick_descr_impl_t sspci_subnicks[1];
1473 } ses2_subnick_status_page_impl_t;
1474 
1475 /*
1476  * SES-2 Mode page code for enclosure services devices (Table 57, 6.3.2).
1477  */
1478 typedef struct ses2_esm_mode_page_impl {
1479 	DECL_BITFIELD3(
1480 	    sempi_page_code	:6,
1481 	    _reserved1		:1,
1482 	    sempi_ps		:1);
1483 	uint8_t sempi_page_length;
1484 	uint8_t _reserved2[3];
1485 	DECL_BITFIELD2(
1486 	    sempi_enbltc	:1,
1487 	    _reserved3		:7);
1488 	uint16_t sempi_max_task_completion_time;
1489 } ses2_esm_mode_page_impl_t;
1490 
1491 #pragma pack()
1492 
1493 extern ses_pagedesc_t ses2_pages[];
1494 
1495 extern int ses2_fill_element_node(ses_plugin_t *, ses_node_t *);
1496 extern int ses2_fill_enclosure_node(ses_plugin_t *, ses_node_t *);
1497 
1498 typedef int (*ses2_setprop_f)(ses_plugin_t *, ses_node_t *, ses2_diag_page_t,
1499     nvpair_t *);
1500 
1501 typedef struct ses2_ctl_prop {
1502 	const char *scp_name;
1503 	data_type_t scp_type;
1504 	ses2_diag_page_t scp_num;
1505 	ses2_setprop_f scp_setprop;
1506 } ses2_ctl_prop_t;
1507 
1508 typedef int (*ses2_setdef_f)(ses_node_t *, ses2_diag_page_t, void *);
1509 
1510 extern int ses2_ctl_common_setprop(ses_plugin_t *sp, ses_node_t *,
1511     ses2_diag_page_t, nvpair_t *);
1512 
1513 #define	SES_COMMON_CTL_PROPS	\
1514 {	\
1515 	.scp_name = SES_PROP_SWAP,	\
1516 	.scp_type = DATA_TYPE_BOOLEAN_VALUE,	\
1517 	.scp_num = SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS,	\
1518 	.scp_setprop = ses2_ctl_common_setprop	\
1519 },	\
1520 {	\
1521 	.scp_name = SES_PROP_DISABLED,	\
1522 	.scp_type = DATA_TYPE_BOOLEAN_VALUE,	\
1523 	.scp_num = SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS,	\
1524 	.scp_setprop = ses2_ctl_common_setprop	\
1525 },	\
1526 {	\
1527 	.scp_name = SES_PROP_PRDFAIL,	\
1528 	.scp_type = DATA_TYPE_BOOLEAN_VALUE,	\
1529 	.scp_num = SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS,	\
1530 	.scp_setprop = ses2_ctl_common_setprop	\
1531 }
1532 
1533 typedef struct ses2_ctl_desc {
1534 	ses2_element_type_t scd_et;
1535 	const ses2_ctl_prop_t *scd_props;
1536 	ses2_setdef_f scd_setdef;
1537 } ses2_ctl_desc_t;
1538 
1539 extern int ses2_setprop(ses_plugin_t *, ses_node_t *, const ses2_ctl_prop_t *,
1540     nvlist_t *);
1541 
1542 extern int ses2_element_setdef(ses_node_t *, ses2_diag_page_t, void *);
1543 extern int ses2_enclosure_setdef(ses_node_t *, ses2_diag_page_t, void *);
1544 
1545 extern int ses2_element_ctl(ses_plugin_t *, ses_node_t *, const char *,
1546     nvlist_t *);
1547 extern int ses2_enclosure_ctl(ses_plugin_t *, ses_node_t *, const char *,
1548     nvlist_t *);
1549 
1550 #ifdef	__cplusplus
1551 }
1552 #endif
1553 
1554 #endif	/* _PLUGIN_SES_IMPL_H */
1555