1275c9da8Seschrock /*
2275c9da8Seschrock  * CDDL HEADER START
3275c9da8Seschrock  *
4275c9da8Seschrock  * The contents of this file are subject to the terms of the
5275c9da8Seschrock  * Common Development and Distribution License (the "License").
6275c9da8Seschrock  * You may not use this file except in compliance with the License.
7275c9da8Seschrock  *
8275c9da8Seschrock  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9275c9da8Seschrock  * or http://www.opensolaris.org/os/licensing.
10275c9da8Seschrock  * See the License for the specific language governing permissions
11275c9da8Seschrock  * and limitations under the License.
12275c9da8Seschrock  *
13275c9da8Seschrock  * When distributing Covered Code, include this CDDL HEADER in each
14275c9da8Seschrock  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15275c9da8Seschrock  * If applicable, add the following below this CDDL HEADER, with the
16275c9da8Seschrock  * fields enclosed by brackets "[]" replaced with your own identifying
17275c9da8Seschrock  * information: Portions Copyright [yyyy] [name of copyright owner]
18275c9da8Seschrock  *
19275c9da8Seschrock  * CDDL HEADER END
20275c9da8Seschrock  */
21275c9da8Seschrock 
22275c9da8Seschrock /*
23ac88567aSHyon Kim  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24275c9da8Seschrock  */
25*a8be79faSAlexander Stetsenko /*
26*a8be79faSAlexander Stetsenko  * Copyright 2012 Nexenta Systems, Inc.  All rights reserved.
27*a8be79faSAlexander Stetsenko  */
28275c9da8Seschrock 
29275c9da8Seschrock #include <stddef.h>
30275c9da8Seschrock #include <strings.h>
31275c9da8Seschrock 
32275c9da8Seschrock #include <scsi/libses.h>
33275c9da8Seschrock #include <scsi/libses_plugin.h>
34275c9da8Seschrock #include <scsi/plugins/ses/framework/ses2.h>
35275c9da8Seschrock 
36275c9da8Seschrock #include "ses2_impl.h"
37275c9da8Seschrock 
38275c9da8Seschrock static int
39275c9da8Seschrock ses2_ctl_common_setdef(ses_node_t *np, ses2_diag_page_t page, void *data)
40275c9da8Seschrock {
41275c9da8Seschrock 	ses2_cmn_elem_ctl_impl_t *eip = data;
42275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
43275c9da8Seschrock 
44275c9da8Seschrock 	if (page != SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS)
45275c9da8Seschrock 		return (0);
46275c9da8Seschrock 
47275c9da8Seschrock 	SES_NV_CTLBOOL_INVERT(props, SES_PROP_SWAP, eip->seci_rst_swap);
48275c9da8Seschrock 	SES_NV_CTLBOOL(props, SES_PROP_DISABLED, eip->seci_disable);
49275c9da8Seschrock 	SES_NV_CTLBOOL(props, SES_PROP_PRDFAIL, eip->seci_prdfail);
50275c9da8Seschrock 
51275c9da8Seschrock 	eip->seci_select = 1;
52275c9da8Seschrock 
53275c9da8Seschrock 	return (0);
54275c9da8Seschrock }
55275c9da8Seschrock 
56275c9da8Seschrock /*ARGSUSED*/
57275c9da8Seschrock static void *
58275c9da8Seschrock ses2_aes_index(ses_plugin_t *sp, ses_node_t *np, void *data, size_t pagelen,
59275c9da8Seschrock     size_t *len)
60275c9da8Seschrock {
61275c9da8Seschrock 	ses2_aes_page_impl_t *apip = data;
62275c9da8Seschrock 	uint64_t index, type;
63275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
64275c9da8Seschrock 	ses2_aes_descr_eip_impl_t *dep;
65275c9da8Seschrock 	size_t desclen;
66275c9da8Seschrock 	int i, pos;
67275c9da8Seschrock 
68ed0f0083SHyon Kim 	VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_ONLY_INDEX,
69275c9da8Seschrock 	    &index) == 0);
70275c9da8Seschrock 	VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_TYPE,
71275c9da8Seschrock 	    &type) == 0);
72275c9da8Seschrock 
73275c9da8Seschrock 	if (pagelen < offsetof(ses2_aes_page_impl_t, sapi_data))
74275c9da8Seschrock 		return (0);
75275c9da8Seschrock 
76275c9da8Seschrock 	for (dep = (ses2_aes_descr_eip_impl_t *)apip->sapi_data, pos = 0, i = 0;
77275c9da8Seschrock 	    pos < SCSI_READ16(&apip->sapi_page_length);
78275c9da8Seschrock 	    dep = (ses2_aes_descr_eip_impl_t *)(apip->sapi_data + pos), i++) {
79275c9da8Seschrock 		if (!SES_WITHIN_PAGE_STRUCT(dep, data, pagelen))
80275c9da8Seschrock 			break;
81275c9da8Seschrock 
82275c9da8Seschrock 		desclen = dep->sadei_length +
83275c9da8Seschrock 		    offsetof(ses2_aes_descr_eip_impl_t, sadei_length) +
84275c9da8Seschrock 		    sizeof (dep->sadei_length);
85275c9da8Seschrock 
86275c9da8Seschrock 		if (!SES_WITHIN_PAGE(dep, desclen, data, pagelen))
87275c9da8Seschrock 			break;
88275c9da8Seschrock 
89275c9da8Seschrock 		pos += desclen;
90275c9da8Seschrock 		if (!dep->sadei_eip &&
91275c9da8Seschrock 		    type != SES_ET_DEVICE &&
92275c9da8Seschrock 		    type != SES_ET_ARRAY_DEVICE) {
93275c9da8Seschrock 			/*
94275c9da8Seschrock 			 * We can't really do anything with this, because
95275c9da8Seschrock 			 * while the standard requires that these descriptors
96275c9da8Seschrock 			 * be in the same order as those in the status page,
97275c9da8Seschrock 			 * some element types may optionally include AES
98275c9da8Seschrock 			 * data.  This means we cannot know which element
99275c9da8Seschrock 			 * this descriptor refers to unless EIP is 1.  Sadly,
100275c9da8Seschrock 			 * the standard only says that this "should" be true.
101275c9da8Seschrock 			 * It's impossible to guess what use this is supposed
102275c9da8Seschrock 			 * to have otherwise.  See 6.1.13.1.
103275c9da8Seschrock 			 */
104275c9da8Seschrock 			continue;
105275c9da8Seschrock 		} else if (dep->sadei_eip &&
106275c9da8Seschrock 		    dep->sadei_element_index != index) {
107ed0f0083SHyon Kim 			/*
108ed0f0083SHyon Kim 			 * The element index field from AES descriptor is
109ed0f0083SHyon Kim 			 * element only index which doesn't include the OVERALL
110ed0f0083SHyon Kim 			 * STATUS fields so we should compare with
111ed0f0083SHyon Kim 			 * SES_PROP_ELEMENT_ONLY_INDEX not
112ed0f0083SHyon Kim 			 * SES_PROP_ELEMENT_INDEX.
113ed0f0083SHyon Kim 			 */
114275c9da8Seschrock 			continue;
115275c9da8Seschrock 		} else if (dep->sadei_eip || i == index) {
116275c9da8Seschrock 			*len = desclen;
117275c9da8Seschrock 			return (dep);
118275c9da8Seschrock 		}
119275c9da8Seschrock 	}
120275c9da8Seschrock 
121275c9da8Seschrock 	return (NULL);
122275c9da8Seschrock }
123275c9da8Seschrock 
124275c9da8Seschrock /*ARGSUSED*/
125275c9da8Seschrock static void *
126275c9da8Seschrock ses2_threshold_index(ses_plugin_t *sp, ses_node_t *np, void *data,
127275c9da8Seschrock     size_t pagelen, size_t *len)
128275c9da8Seschrock {
129275c9da8Seschrock 	uint64_t index;
130275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
131275c9da8Seschrock 	ses2_threshold_in_page_impl_t *tpip = data;
132275c9da8Seschrock 	ses2_threshold_impl_t *tp;
133275c9da8Seschrock 
134275c9da8Seschrock 	VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_INDEX,
135275c9da8Seschrock 	    &index) == 0);
136275c9da8Seschrock 
137275c9da8Seschrock 	*len = sizeof (ses2_threshold_impl_t);
138275c9da8Seschrock 	tp = &tpip->stipi_thresholds[index];
139275c9da8Seschrock 
140275c9da8Seschrock 	if (!SES_WITHIN_PAGE_STRUCT(tp, data, pagelen))
141275c9da8Seschrock 		return (NULL);
142275c9da8Seschrock 
143275c9da8Seschrock 	return (&tpip->stipi_thresholds[index]);
144275c9da8Seschrock }
145275c9da8Seschrock 
146275c9da8Seschrock /*ARGSUSED*/
147275c9da8Seschrock static void *
148275c9da8Seschrock ses2_element_index(ses_plugin_t *sp, ses_node_t *np, void *data,
149275c9da8Seschrock     size_t pagelen, size_t *len)
150275c9da8Seschrock {
151275c9da8Seschrock 	uint64_t index;
152275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
153275c9da8Seschrock 	ses2_elem_desc_page_impl_t *edip = data;
154275c9da8Seschrock 	ses2_elem_descriptor_impl_t *dp;
155275c9da8Seschrock 	int i;
156275c9da8Seschrock 	uint16_t dlen;
157275c9da8Seschrock 
158275c9da8Seschrock 	if (nvlist_lookup_uint64(props, SES_PROP_ELEMENT_INDEX, &index) != 0)
159275c9da8Seschrock 		return (NULL);
160275c9da8Seschrock 
161275c9da8Seschrock 	if (!SES_WITHIN_PAGE(data, sizeof (*dp), data, pagelen))
162275c9da8Seschrock 		return (NULL);
163275c9da8Seschrock 
164275c9da8Seschrock 	/*
165275c9da8Seschrock 	 * This variable-length list of variable-length strings format sucks
166275c9da8Seschrock 	 * for performance; we ALWAYS have to walk the whole bloody thing to
167275c9da8Seschrock 	 * find a particular node's entry.
168275c9da8Seschrock 	 */
169275c9da8Seschrock 	for (i = 0, dp = (ses2_elem_descriptor_impl_t *)edip->sedpi_data;
170275c9da8Seschrock 	    i < index; i++) {
171275c9da8Seschrock 
172275c9da8Seschrock 		if (!SES_WITHIN_PAGE_STRUCT(dp, data, pagelen))
173275c9da8Seschrock 			return (NULL);
174275c9da8Seschrock 
175275c9da8Seschrock 		dlen = SCSI_READ16(&dp->sedi_descriptor_length);
176275c9da8Seschrock 
177275c9da8Seschrock 		dp = (ses2_elem_descriptor_impl_t *)
178275c9da8Seschrock 		    ((uint8_t *)dp->sedi_descriptor + dlen);
179275c9da8Seschrock 	}
180275c9da8Seschrock 
181275c9da8Seschrock 	if (!SES_WITHIN_PAGE_STRUCT(dp, data, pagelen))
182275c9da8Seschrock 		return (NULL);
183275c9da8Seschrock 
184275c9da8Seschrock 	*len = SCSI_READ16(&dp->sedi_descriptor_length);
185275c9da8Seschrock 
186275c9da8Seschrock 	if (!SES_WITHIN_PAGE(dp,
187275c9da8Seschrock 	    *len + offsetof(ses2_elem_descriptor_impl_t, sedi_descriptor),
188275c9da8Seschrock 	    data, pagelen))
189275c9da8Seschrock 		return (NULL);
190275c9da8Seschrock 
191275c9da8Seschrock 	return (dp->sedi_descriptor);
192275c9da8Seschrock }
193275c9da8Seschrock 
194275c9da8Seschrock /*ARGSUSED*/
195275c9da8Seschrock static void *
196275c9da8Seschrock ses2_status_index(ses_plugin_t *sp, ses_node_t *np, void *data,
197275c9da8Seschrock     size_t pagelen, size_t *len)
198275c9da8Seschrock {
199275c9da8Seschrock 	uint64_t index;
200275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
201275c9da8Seschrock 	ses2_status_page_impl_t *spip = data;
202275c9da8Seschrock 
203275c9da8Seschrock 	if (nvlist_lookup_uint64(props, SES_PROP_ELEMENT_INDEX,
204275c9da8Seschrock 	    &index) != 0)
205275c9da8Seschrock 		return (NULL);
206275c9da8Seschrock 
207275c9da8Seschrock 	if ((index + 1) * sizeof (ses2_elem_status_impl_t) +
208275c9da8Seschrock 	    offsetof(ses2_status_page_impl_t, sspi_data) > pagelen)
209275c9da8Seschrock 		return (NULL);
210275c9da8Seschrock 
211275c9da8Seschrock 	*len = sizeof (ses2_elem_status_impl_t);
212275c9da8Seschrock 	return ((ses2_elem_status_impl_t *)spip->sspi_data + index);
213275c9da8Seschrock }
214275c9da8Seschrock 
215275c9da8Seschrock /*ARGSUSED*/
216275c9da8Seschrock static size_t
217275c9da8Seschrock ses2_ctl_len(uint_t nelem, int page, size_t datalen)
218275c9da8Seschrock {
219275c9da8Seschrock 	ASSERT(page == SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS);
220275c9da8Seschrock 
221275c9da8Seschrock 	return (nelem * sizeof (ses2_elem_ctl_impl_t) +
222275c9da8Seschrock 	    offsetof(ses2_control_page_impl_t, scpi_data[0]));
223275c9da8Seschrock }
224275c9da8Seschrock 
225275c9da8Seschrock /*ARGSUSED*/
226275c9da8Seschrock static void *
227275c9da8Seschrock ses2_ctl_fill(ses_plugin_t *sp, void *pagedata, size_t pagelen,
228275c9da8Seschrock     ses_node_t *np)
229275c9da8Seschrock {
230275c9da8Seschrock 	uint64_t index;
231275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
232275c9da8Seschrock 	ses2_control_page_impl_t *pip = pagedata;
233*a8be79faSAlexander Stetsenko 	ses2_elem_ctl_impl_t *eip;
234275c9da8Seschrock 	void *data;
235275c9da8Seschrock 	ses2_diag_page_t page = SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS;
236275c9da8Seschrock 
237275c9da8Seschrock 	if (nvlist_lookup_uint64(props, SES_PROP_ELEMENT_INDEX,
238275c9da8Seschrock 	    &index) != 0) {
239275c9da8Seschrock 		(void) ses_error(ESES_BAD_RESPONSE, "missing element index "
240275c9da8Seschrock 		    "for enclosure node");
241275c9da8Seschrock 		return (NULL);
242275c9da8Seschrock 	}
243275c9da8Seschrock 
244*a8be79faSAlexander Stetsenko 	data = eip = &pip->scpi_data[index];
245*a8be79faSAlexander Stetsenko 	/*
246*a8be79faSAlexander Stetsenko 	 * if control element was already modified "select" field is non-zero,
247*a8be79faSAlexander Stetsenko 	 * so skip setting default values to avoid fields overriding
248*a8be79faSAlexander Stetsenko 	 */
249*a8be79faSAlexander Stetsenko 	if (eip->seci_common.seci_select)
250*a8be79faSAlexander Stetsenko 		return (data);
251275c9da8Seschrock 
252275c9da8Seschrock 	if (ses2_ctl_common_setdef(np, page, data) != 0 ||
253275c9da8Seschrock 	    ses2_element_setdef(np, page, data) != 0 ||
254275c9da8Seschrock 	    ses2_enclosure_setdef(np, page, data) != 0)
255275c9da8Seschrock 		return (NULL);
256275c9da8Seschrock 
257275c9da8Seschrock 	return (data);
258275c9da8Seschrock }
259275c9da8Seschrock 
260275c9da8Seschrock /*ARGSUSED*/
261275c9da8Seschrock static size_t
262275c9da8Seschrock ses2_stringout_len(uint_t nelem, int page, size_t datalen)
263275c9da8Seschrock {
264275c9da8Seschrock 	ASSERT(page == SES2_DIAGPAGE_STRING_IO);
265275c9da8Seschrock 
266275c9da8Seschrock 	return (datalen + offsetof(ses2_string_out_page_impl_t, ssopi_data[0]));
267275c9da8Seschrock }
268275c9da8Seschrock 
269275c9da8Seschrock /*ARGSUSED*/
270275c9da8Seschrock static size_t
271275c9da8Seschrock ses2_threshout_len(uint_t nelem, int page, size_t datalen)
272275c9da8Seschrock {
273275c9da8Seschrock 	ASSERT(page == SES2_DIAGPAGE_THRESHOLD_IO);
274275c9da8Seschrock 
275275c9da8Seschrock 	return (nelem * sizeof (ses2_threshold_impl_t) +
276275c9da8Seschrock 	    offsetof(ses2_threshold_out_page_impl_t, stopi_thresholds[0]));
277275c9da8Seschrock }
278275c9da8Seschrock 
279275c9da8Seschrock /*ARGSUSED*/
280275c9da8Seschrock static void *
281275c9da8Seschrock ses2_threshout_ctl_fill(ses_plugin_t *sp, void *pagedata, size_t pagelen,
282275c9da8Seschrock     ses_node_t *np)
283275c9da8Seschrock {
284275c9da8Seschrock 	uint64_t index;
285275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
286275c9da8Seschrock 	ses2_threshold_out_page_impl_t *pip = pagedata;
287*a8be79faSAlexander Stetsenko 	ses2_threshold_impl_t *tip;
288275c9da8Seschrock 	ses2_diag_page_t page = SES2_DIAGPAGE_THRESHOLD_IO;
289275c9da8Seschrock 	void *data;
290275c9da8Seschrock 
291275c9da8Seschrock 	VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_INDEX,
292275c9da8Seschrock 	    &index) == 0);
293275c9da8Seschrock 
294*a8be79faSAlexander Stetsenko 	data = tip = &pip->stopi_thresholds[index];
295275c9da8Seschrock 
296*a8be79faSAlexander Stetsenko 	/* check if threshold is dirty, so no need to set default values */
297*a8be79faSAlexander Stetsenko 	if ((tip->sti_high_crit | tip->sti_low_crit | tip->sti_high_warn |
298*a8be79faSAlexander Stetsenko 	    tip->sti_low_warn) != 0)
299*a8be79faSAlexander Stetsenko 		return (data);
300*a8be79faSAlexander Stetsenko 
301*a8be79faSAlexander Stetsenko 	if (ses2_element_setdef(np, page, data) != 0)
302275c9da8Seschrock 		return (NULL);
303275c9da8Seschrock 
304275c9da8Seschrock 	return (data);
305275c9da8Seschrock }
306275c9da8Seschrock 
307275c9da8Seschrock /*ARGSUSED*/
308275c9da8Seschrock static size_t
309275c9da8Seschrock ses2_substrout_len(uint_t nelem, int page, size_t datalen)
310275c9da8Seschrock {
311275c9da8Seschrock 	ASSERT(page == SES2_DIAGPAGE_SUBENCLOSURE_STRING_IO);
312275c9da8Seschrock 
313275c9da8Seschrock 	return (datalen +
314275c9da8Seschrock 	    offsetof(ses2_substring_out_page_impl_t, ssopi_data[0]));
315275c9da8Seschrock }
316275c9da8Seschrock 
317275c9da8Seschrock /*ARGSUSED*/
318275c9da8Seschrock static size_t
319275c9da8Seschrock ses2_ucodeout_len(uint_t nelem, int page, size_t datalen)
320275c9da8Seschrock {
321275c9da8Seschrock 	size_t len;
322275c9da8Seschrock 
323275c9da8Seschrock 	ASSERT(page == SES2_DIAGPAGE_DL_MICROCODE_CTL_STATUS);
324275c9da8Seschrock 
325275c9da8Seschrock 	len = datalen +
326275c9da8Seschrock 	    offsetof(ses2_ucode_ctl_page_impl_t, sucpi_ucode_data[0]);
327275c9da8Seschrock 
328275c9da8Seschrock 	return (P2ROUNDUP(len, 4));
329275c9da8Seschrock }
330275c9da8Seschrock 
331275c9da8Seschrock /*ARGSUSED*/
332275c9da8Seschrock static void *
333275c9da8Seschrock ses2_ucodeout_ctl_fill(ses_plugin_t *sp, void *data, size_t pagelen,
334275c9da8Seschrock     ses_node_t *np)
335275c9da8Seschrock {
336275c9da8Seschrock 	ses_snap_t *snap = ses_node_snapshot(np);
337275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
338275c9da8Seschrock 	ses2_ucode_ctl_page_impl_t *uip = data;
339275c9da8Seschrock 	uint64_t eid;
340275c9da8Seschrock 
341275c9da8Seschrock 	if (ses_node_type(np) != SES_NODE_ENCLOSURE) {
342275c9da8Seschrock 		(void) ses_error(ESES_BAD_TYPE,
343275c9da8Seschrock 		    "microcode download page only valid for enclosure "
344275c9da8Seschrock 		    "nodes");
345275c9da8Seschrock 		return (NULL);
346275c9da8Seschrock 	}
347275c9da8Seschrock 
348275c9da8Seschrock 	VERIFY(nvlist_lookup_uint64(props, SES_EN_PROP_EID, &eid) == 0);
349275c9da8Seschrock 
350275c9da8Seschrock 	SCSI_WRITE32(&uip->sucpi_generation_code,
351275c9da8Seschrock 	    ses_snap_generation(snap));
352275c9da8Seschrock 	uip->sucpi_subenclosure_identifier = eid;
353275c9da8Seschrock 
354275c9da8Seschrock 	return (data);
355275c9da8Seschrock }
356275c9da8Seschrock 
357275c9da8Seschrock /*ARGSUSED*/
358275c9da8Seschrock static size_t
359275c9da8Seschrock ses2_subnickout_len(uint_t nelem, int page, size_t datalen)
360275c9da8Seschrock {
361275c9da8Seschrock 	ASSERT(page == SES2_DIAGPAGE_SUBENCLOSURE_NICKNAME_CTL_STATUS);
362275c9da8Seschrock 
363275c9da8Seschrock 	return (sizeof (ses2_subnick_ctl_page_impl_t));
364275c9da8Seschrock }
365275c9da8Seschrock 
366275c9da8Seschrock ses_pagedesc_t ses2_pages[] = {
367275c9da8Seschrock {
368275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_SUPPORTED_PAGES,
369ac88567aSHyon Kim 	.spd_req = SES_REQ_MANDATORY_ALL,
370275c9da8Seschrock 	.spd_gcoff = -1
371275c9da8Seschrock },
372275c9da8Seschrock {
373275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_CONFIG,
374ac88567aSHyon Kim 	.spd_req = SES_REQ_MANDATORY_STANDARD,
375275c9da8Seschrock 	.spd_gcoff = offsetof(ses2_config_page_impl_t, scpi_generation_code)
376275c9da8Seschrock },
377275c9da8Seschrock {
378275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS,
379ac88567aSHyon Kim 	.spd_req = SES_REQ_MANDATORY_STANDARD,
380275c9da8Seschrock 	.spd_index = ses2_status_index,
381275c9da8Seschrock 	.spd_gcoff = offsetof(ses2_status_page_impl_t, sspi_generation_code)
382275c9da8Seschrock },
383275c9da8Seschrock {
384275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_HELP_TEXT,
385ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
386275c9da8Seschrock 	.spd_gcoff = -1
387275c9da8Seschrock },
388275c9da8Seschrock {
389275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_STRING_IO,
390ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
391275c9da8Seschrock 	.spd_gcoff = -1
392275c9da8Seschrock },
393275c9da8Seschrock {
394275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_THRESHOLD_IO,
395275c9da8Seschrock 	.spd_index = ses2_threshold_index,
396ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
397275c9da8Seschrock 	.spd_gcoff =
398275c9da8Seschrock 	    offsetof(ses2_threshold_in_page_impl_t, stipi_generation_code)
399275c9da8Seschrock },
400275c9da8Seschrock {
401275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_ELEMENT_DESC,
402275c9da8Seschrock 	.spd_index = ses2_element_index,
403ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
404275c9da8Seschrock 	.spd_gcoff = offsetof(ses2_elem_desc_page_impl_t, sedpi_generation_code)
405275c9da8Seschrock },
406275c9da8Seschrock {
407275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_ADDL_ELEM_STATUS,
408275c9da8Seschrock 	.spd_index = ses2_aes_index,
409ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
410275c9da8Seschrock 	.spd_gcoff = offsetof(ses2_aes_page_impl_t, sapi_generation_code)
411275c9da8Seschrock },
412275c9da8Seschrock {
413275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_SUBENCLOSURE_HELP_TEXT,
414ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
415275c9da8Seschrock 	.spd_gcoff = offsetof(ses2_subhelp_page_impl_t, sspi_generation_code)
416275c9da8Seschrock },
417275c9da8Seschrock {
418275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_SUBENCLOSURE_STRING_IO,
419ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
420275c9da8Seschrock 	.spd_gcoff =
421275c9da8Seschrock 	    offsetof(ses2_substring_in_page_impl_t, ssipi_generation_code)
422275c9da8Seschrock },
423275c9da8Seschrock {
424275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_SUPPORTED_SES_PAGES,
425ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
426275c9da8Seschrock 	.spd_gcoff = -1
427275c9da8Seschrock },
428275c9da8Seschrock {
429275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_DL_MICROCODE_CTL_STATUS,
430ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
431275c9da8Seschrock 	.spd_gcoff =
432275c9da8Seschrock 	    offsetof(ses2_ucode_status_page_impl_t, suspi_generation_code)
433275c9da8Seschrock },
434275c9da8Seschrock {
435275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_SUBENCLOSURE_NICKNAME_CTL_STATUS,
436ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
437275c9da8Seschrock 	.spd_gcoff =
438275c9da8Seschrock 	    offsetof(ses2_subnick_status_page_impl_t, sspci_generation_code)
439275c9da8Seschrock },
440275c9da8Seschrock /* Control pages */
441275c9da8Seschrock {
442275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS,
443275c9da8Seschrock 	.spd_ctl_len = ses2_ctl_len,
444275c9da8Seschrock 	.spd_ctl_fill = ses2_ctl_fill,
445ac88567aSHyon Kim 	.spd_req = SES_REQ_MANDATORY_STANDARD,
446275c9da8Seschrock 	.spd_gcoff = offsetof(ses2_control_page_impl_t, scpi_generation_code)
447275c9da8Seschrock },
448275c9da8Seschrock {
449275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_STRING_IO,
450275c9da8Seschrock 	.spd_ctl_len = ses2_stringout_len,
451ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
452275c9da8Seschrock 	.spd_gcoff = -1
453275c9da8Seschrock },
454275c9da8Seschrock {
455275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_THRESHOLD_IO,
456275c9da8Seschrock 	.spd_ctl_len = ses2_threshout_len,
457275c9da8Seschrock 	.spd_ctl_fill = ses2_threshout_ctl_fill,
458ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
459275c9da8Seschrock 	.spd_gcoff =
460275c9da8Seschrock 	    offsetof(ses2_threshold_out_page_impl_t, stopi_generation_code)
461275c9da8Seschrock },
462275c9da8Seschrock {
463275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_SUBENCLOSURE_STRING_IO,
464275c9da8Seschrock 	.spd_ctl_len = ses2_substrout_len,
465ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
466275c9da8Seschrock 	.spd_gcoff =
467275c9da8Seschrock 	    offsetof(ses2_substring_out_page_impl_t, ssopi_generation_code)
468275c9da8Seschrock },
469275c9da8Seschrock {
470275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_DL_MICROCODE_CTL_STATUS,
471275c9da8Seschrock 	.spd_ctl_len = ses2_ucodeout_len,
472275c9da8Seschrock 	.spd_ctl_fill = ses2_ucodeout_ctl_fill,
473ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
474275c9da8Seschrock 	.spd_gcoff =
475275c9da8Seschrock 	    offsetof(ses2_ucode_ctl_page_impl_t, sucpi_generation_code)
476275c9da8Seschrock },
477275c9da8Seschrock {
478275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_SUBENCLOSURE_NICKNAME_CTL_STATUS,
479275c9da8Seschrock 	.spd_ctl_len = ses2_subnickout_len,
480ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
481275c9da8Seschrock 	.spd_gcoff =
482275c9da8Seschrock 	    offsetof(ses2_subnick_ctl_page_impl_t, sspci_generation_code)
483275c9da8Seschrock },
484275c9da8Seschrock {
485275c9da8Seschrock 	.spd_pagenum = -1,
486275c9da8Seschrock 	.spd_gcoff = -1
487275c9da8Seschrock }
488275c9da8Seschrock };
489