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 /*
23*ac88567aSHyon Kim  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24275c9da8Seschrock  */
25275c9da8Seschrock 
26275c9da8Seschrock #include <stddef.h>
27275c9da8Seschrock #include <strings.h>
28275c9da8Seschrock 
29275c9da8Seschrock #include <scsi/libses.h>
30275c9da8Seschrock #include <scsi/libses_plugin.h>
31275c9da8Seschrock #include <scsi/plugins/ses/framework/ses2.h>
32275c9da8Seschrock 
33275c9da8Seschrock #include "ses2_impl.h"
34275c9da8Seschrock 
35275c9da8Seschrock static int
36275c9da8Seschrock ses2_ctl_common_setdef(ses_node_t *np, ses2_diag_page_t page, void *data)
37275c9da8Seschrock {
38275c9da8Seschrock 	ses2_cmn_elem_ctl_impl_t *eip = data;
39275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
40275c9da8Seschrock 
41275c9da8Seschrock 	if (page != SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS)
42275c9da8Seschrock 		return (0);
43275c9da8Seschrock 
44275c9da8Seschrock 	SES_NV_CTLBOOL_INVERT(props, SES_PROP_SWAP, eip->seci_rst_swap);
45275c9da8Seschrock 	SES_NV_CTLBOOL(props, SES_PROP_DISABLED, eip->seci_disable);
46275c9da8Seschrock 	SES_NV_CTLBOOL(props, SES_PROP_PRDFAIL, eip->seci_prdfail);
47275c9da8Seschrock 
48275c9da8Seschrock 	eip->seci_select = 1;
49275c9da8Seschrock 
50275c9da8Seschrock 	return (0);
51275c9da8Seschrock }
52275c9da8Seschrock 
53275c9da8Seschrock /*ARGSUSED*/
54275c9da8Seschrock static void *
55275c9da8Seschrock ses2_aes_index(ses_plugin_t *sp, ses_node_t *np, void *data, size_t pagelen,
56275c9da8Seschrock     size_t *len)
57275c9da8Seschrock {
58275c9da8Seschrock 	ses2_aes_page_impl_t *apip = data;
59275c9da8Seschrock 	uint64_t index, type;
60275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
61275c9da8Seschrock 	ses2_aes_descr_eip_impl_t *dep;
62275c9da8Seschrock 	size_t desclen;
63275c9da8Seschrock 	int i, pos;
64275c9da8Seschrock 	ses_node_t *uncle;
65275c9da8Seschrock 
66275c9da8Seschrock 	VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_INDEX,
67275c9da8Seschrock 	    &index) == 0);
68275c9da8Seschrock 	VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_TYPE,
69275c9da8Seschrock 	    &type) == 0);
70275c9da8Seschrock 
71275c9da8Seschrock 	if (pagelen < offsetof(ses2_aes_page_impl_t, sapi_data))
72275c9da8Seschrock 		return (0);
73275c9da8Seschrock 
74275c9da8Seschrock 	/*
75275c9da8Seschrock 	 * Because, according to 6.1.13.1, the element index "does not
76275c9da8Seschrock 	 * include the OVERALL STATUS fields", we have to go recompute the
77275c9da8Seschrock 	 * index of this element each time.  This, naturally, is a linear
78275c9da8Seschrock 	 * exercise as well.
79275c9da8Seschrock 	 */
80275c9da8Seschrock 	for (uncle = ses_node_parent(np); uncle != NULL;
81275c9da8Seschrock 	    uncle = ses_node_prev_sibling(uncle))
82275c9da8Seschrock 		--index;
83275c9da8Seschrock 
84275c9da8Seschrock 	for (dep = (ses2_aes_descr_eip_impl_t *)apip->sapi_data, pos = 0, i = 0;
85275c9da8Seschrock 	    pos < SCSI_READ16(&apip->sapi_page_length);
86275c9da8Seschrock 	    dep = (ses2_aes_descr_eip_impl_t *)(apip->sapi_data + pos), i++) {
87275c9da8Seschrock 		if (!SES_WITHIN_PAGE_STRUCT(dep, data, pagelen))
88275c9da8Seschrock 			break;
89275c9da8Seschrock 
90275c9da8Seschrock 		desclen = dep->sadei_length +
91275c9da8Seschrock 		    offsetof(ses2_aes_descr_eip_impl_t, sadei_length) +
92275c9da8Seschrock 		    sizeof (dep->sadei_length);
93275c9da8Seschrock 
94275c9da8Seschrock 		if (!SES_WITHIN_PAGE(dep, desclen, data, pagelen))
95275c9da8Seschrock 			break;
96275c9da8Seschrock 
97275c9da8Seschrock 		pos += desclen;
98275c9da8Seschrock 		if (!dep->sadei_eip &&
99275c9da8Seschrock 		    type != SES_ET_DEVICE &&
100275c9da8Seschrock 		    type != SES_ET_ARRAY_DEVICE) {
101275c9da8Seschrock 			/*
102275c9da8Seschrock 			 * We can't really do anything with this, because
103275c9da8Seschrock 			 * while the standard requires that these descriptors
104275c9da8Seschrock 			 * be in the same order as those in the status page,
105275c9da8Seschrock 			 * some element types may optionally include AES
106275c9da8Seschrock 			 * data.  This means we cannot know which element
107275c9da8Seschrock 			 * this descriptor refers to unless EIP is 1.  Sadly,
108275c9da8Seschrock 			 * the standard only says that this "should" be true.
109275c9da8Seschrock 			 * It's impossible to guess what use this is supposed
110275c9da8Seschrock 			 * to have otherwise.  See 6.1.13.1.
111275c9da8Seschrock 			 */
112275c9da8Seschrock 			continue;
113275c9da8Seschrock 		} else if (dep->sadei_eip &&
114275c9da8Seschrock 		    dep->sadei_element_index != index) {
115275c9da8Seschrock 			continue;
116275c9da8Seschrock 		} else if (dep->sadei_eip || i == index) {
117275c9da8Seschrock 			*len = desclen;
118275c9da8Seschrock 			return (dep);
119275c9da8Seschrock 		}
120275c9da8Seschrock 	}
121275c9da8Seschrock 
122275c9da8Seschrock 	return (NULL);
123275c9da8Seschrock }
124275c9da8Seschrock 
125275c9da8Seschrock /*ARGSUSED*/
126275c9da8Seschrock static void *
127275c9da8Seschrock ses2_threshold_index(ses_plugin_t *sp, ses_node_t *np, void *data,
128275c9da8Seschrock     size_t pagelen, size_t *len)
129275c9da8Seschrock {
130275c9da8Seschrock 	uint64_t index;
131275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
132275c9da8Seschrock 	ses2_threshold_in_page_impl_t *tpip = data;
133275c9da8Seschrock 	ses2_threshold_impl_t *tp;
134275c9da8Seschrock 
135275c9da8Seschrock 	VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_INDEX,
136275c9da8Seschrock 	    &index) == 0);
137275c9da8Seschrock 
138275c9da8Seschrock 	*len = sizeof (ses2_threshold_impl_t);
139275c9da8Seschrock 	tp = &tpip->stipi_thresholds[index];
140275c9da8Seschrock 
141275c9da8Seschrock 	if (!SES_WITHIN_PAGE_STRUCT(tp, data, pagelen))
142275c9da8Seschrock 		return (NULL);
143275c9da8Seschrock 
144275c9da8Seschrock 	return (&tpip->stipi_thresholds[index]);
145275c9da8Seschrock }
146275c9da8Seschrock 
147275c9da8Seschrock /*ARGSUSED*/
148275c9da8Seschrock static void *
149275c9da8Seschrock ses2_element_index(ses_plugin_t *sp, ses_node_t *np, void *data,
150275c9da8Seschrock     size_t pagelen, size_t *len)
151275c9da8Seschrock {
152275c9da8Seschrock 	uint64_t index;
153275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
154275c9da8Seschrock 	ses2_elem_desc_page_impl_t *edip = data;
155275c9da8Seschrock 	ses2_elem_descriptor_impl_t *dp;
156275c9da8Seschrock 	int i;
157275c9da8Seschrock 	uint16_t dlen;
158275c9da8Seschrock 
159275c9da8Seschrock 	if (nvlist_lookup_uint64(props, SES_PROP_ELEMENT_INDEX, &index) != 0)
160275c9da8Seschrock 		return (NULL);
161275c9da8Seschrock 
162275c9da8Seschrock 	if (!SES_WITHIN_PAGE(data, sizeof (*dp), data, pagelen))
163275c9da8Seschrock 		return (NULL);
164275c9da8Seschrock 
165275c9da8Seschrock 	/*
166275c9da8Seschrock 	 * This variable-length list of variable-length strings format sucks
167275c9da8Seschrock 	 * for performance; we ALWAYS have to walk the whole bloody thing to
168275c9da8Seschrock 	 * find a particular node's entry.
169275c9da8Seschrock 	 */
170275c9da8Seschrock 	for (i = 0, dp = (ses2_elem_descriptor_impl_t *)edip->sedpi_data;
171275c9da8Seschrock 	    i < index; i++) {
172275c9da8Seschrock 
173275c9da8Seschrock 		if (!SES_WITHIN_PAGE_STRUCT(dp, data, pagelen))
174275c9da8Seschrock 			return (NULL);
175275c9da8Seschrock 
176275c9da8Seschrock 		dlen = SCSI_READ16(&dp->sedi_descriptor_length);
177275c9da8Seschrock 
178275c9da8Seschrock 		dp = (ses2_elem_descriptor_impl_t *)
179275c9da8Seschrock 		    ((uint8_t *)dp->sedi_descriptor + dlen);
180275c9da8Seschrock 	}
181275c9da8Seschrock 
182275c9da8Seschrock 	if (!SES_WITHIN_PAGE_STRUCT(dp, data, pagelen))
183275c9da8Seschrock 		return (NULL);
184275c9da8Seschrock 
185275c9da8Seschrock 	*len = SCSI_READ16(&dp->sedi_descriptor_length);
186275c9da8Seschrock 
187275c9da8Seschrock 	if (!SES_WITHIN_PAGE(dp,
188275c9da8Seschrock 	    *len + offsetof(ses2_elem_descriptor_impl_t, sedi_descriptor),
189275c9da8Seschrock 	    data, pagelen))
190275c9da8Seschrock 		return (NULL);
191275c9da8Seschrock 
192275c9da8Seschrock 	return (dp->sedi_descriptor);
193275c9da8Seschrock }
194275c9da8Seschrock 
195275c9da8Seschrock /*ARGSUSED*/
196275c9da8Seschrock static void *
197275c9da8Seschrock ses2_status_index(ses_plugin_t *sp, ses_node_t *np, void *data,
198275c9da8Seschrock     size_t pagelen, size_t *len)
199275c9da8Seschrock {
200275c9da8Seschrock 	uint64_t index;
201275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
202275c9da8Seschrock 	ses2_status_page_impl_t *spip = data;
203275c9da8Seschrock 
204275c9da8Seschrock 	if (nvlist_lookup_uint64(props, SES_PROP_ELEMENT_INDEX,
205275c9da8Seschrock 	    &index) != 0)
206275c9da8Seschrock 		return (NULL);
207275c9da8Seschrock 
208275c9da8Seschrock 	if ((index + 1) * sizeof (ses2_elem_status_impl_t) +
209275c9da8Seschrock 	    offsetof(ses2_status_page_impl_t, sspi_data) > pagelen)
210275c9da8Seschrock 		return (NULL);
211275c9da8Seschrock 
212275c9da8Seschrock 	*len = sizeof (ses2_elem_status_impl_t);
213275c9da8Seschrock 	return ((ses2_elem_status_impl_t *)spip->sspi_data + index);
214275c9da8Seschrock }
215275c9da8Seschrock 
216275c9da8Seschrock /*ARGSUSED*/
217275c9da8Seschrock static size_t
218275c9da8Seschrock ses2_ctl_len(uint_t nelem, int page, size_t datalen)
219275c9da8Seschrock {
220275c9da8Seschrock 	ASSERT(page == SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS);
221275c9da8Seschrock 
222275c9da8Seschrock 	return (nelem * sizeof (ses2_elem_ctl_impl_t) +
223275c9da8Seschrock 	    offsetof(ses2_control_page_impl_t, scpi_data[0]));
224275c9da8Seschrock }
225275c9da8Seschrock 
226275c9da8Seschrock /*ARGSUSED*/
227275c9da8Seschrock static void *
228275c9da8Seschrock ses2_ctl_fill(ses_plugin_t *sp, void *pagedata, size_t pagelen,
229275c9da8Seschrock     ses_node_t *np)
230275c9da8Seschrock {
231275c9da8Seschrock 	uint64_t index;
232275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
233275c9da8Seschrock 	ses2_control_page_impl_t *pip = pagedata;
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 
244275c9da8Seschrock 	data = &pip->scpi_data[index];
245275c9da8Seschrock 
246275c9da8Seschrock 	if (ses2_ctl_common_setdef(np, page, data) != 0 ||
247275c9da8Seschrock 	    ses2_element_setdef(np, page, data) != 0 ||
248275c9da8Seschrock 	    ses2_enclosure_setdef(np, page, data) != 0)
249275c9da8Seschrock 		return (NULL);
250275c9da8Seschrock 
251275c9da8Seschrock 	return (data);
252275c9da8Seschrock }
253275c9da8Seschrock 
254275c9da8Seschrock /*ARGSUSED*/
255275c9da8Seschrock static size_t
256275c9da8Seschrock ses2_stringout_len(uint_t nelem, int page, size_t datalen)
257275c9da8Seschrock {
258275c9da8Seschrock 	ASSERT(page == SES2_DIAGPAGE_STRING_IO);
259275c9da8Seschrock 
260275c9da8Seschrock 	return (datalen + offsetof(ses2_string_out_page_impl_t, ssopi_data[0]));
261275c9da8Seschrock }
262275c9da8Seschrock 
263275c9da8Seschrock /*ARGSUSED*/
264275c9da8Seschrock static size_t
265275c9da8Seschrock ses2_threshout_len(uint_t nelem, int page, size_t datalen)
266275c9da8Seschrock {
267275c9da8Seschrock 	ASSERT(page == SES2_DIAGPAGE_THRESHOLD_IO);
268275c9da8Seschrock 
269275c9da8Seschrock 	return (nelem * sizeof (ses2_threshold_impl_t) +
270275c9da8Seschrock 	    offsetof(ses2_threshold_out_page_impl_t, stopi_thresholds[0]));
271275c9da8Seschrock }
272275c9da8Seschrock 
273275c9da8Seschrock /*ARGSUSED*/
274275c9da8Seschrock static void *
275275c9da8Seschrock ses2_threshout_ctl_fill(ses_plugin_t *sp, void *pagedata, size_t pagelen,
276275c9da8Seschrock     ses_node_t *np)
277275c9da8Seschrock {
278275c9da8Seschrock 	uint64_t index;
279275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
280275c9da8Seschrock 	ses2_threshold_out_page_impl_t *pip = pagedata;
281275c9da8Seschrock 	ses2_diag_page_t page = SES2_DIAGPAGE_THRESHOLD_IO;
282275c9da8Seschrock 	void *data;
283275c9da8Seschrock 
284275c9da8Seschrock 	VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_INDEX,
285275c9da8Seschrock 	    &index) == 0);
286275c9da8Seschrock 
287275c9da8Seschrock 	data = &pip[index];
288275c9da8Seschrock 
289275c9da8Seschrock 	if (ses2_ctl_common_setdef(np, page, data) != 0 ||
290275c9da8Seschrock 	    ses2_element_setdef(np, page, data) != 0 ||
291275c9da8Seschrock 	    ses2_enclosure_setdef(np, page, data) != 0)
292275c9da8Seschrock 		return (NULL);
293275c9da8Seschrock 
294275c9da8Seschrock 	return (data);
295275c9da8Seschrock }
296275c9da8Seschrock 
297275c9da8Seschrock /*ARGSUSED*/
298275c9da8Seschrock static size_t
299275c9da8Seschrock ses2_substrout_len(uint_t nelem, int page, size_t datalen)
300275c9da8Seschrock {
301275c9da8Seschrock 	ASSERT(page == SES2_DIAGPAGE_SUBENCLOSURE_STRING_IO);
302275c9da8Seschrock 
303275c9da8Seschrock 	return (datalen +
304275c9da8Seschrock 	    offsetof(ses2_substring_out_page_impl_t, ssopi_data[0]));
305275c9da8Seschrock }
306275c9da8Seschrock 
307275c9da8Seschrock /*ARGSUSED*/
308275c9da8Seschrock static size_t
309275c9da8Seschrock ses2_ucodeout_len(uint_t nelem, int page, size_t datalen)
310275c9da8Seschrock {
311275c9da8Seschrock 	size_t len;
312275c9da8Seschrock 
313275c9da8Seschrock 	ASSERT(page == SES2_DIAGPAGE_DL_MICROCODE_CTL_STATUS);
314275c9da8Seschrock 
315275c9da8Seschrock 	len = datalen +
316275c9da8Seschrock 	    offsetof(ses2_ucode_ctl_page_impl_t, sucpi_ucode_data[0]);
317275c9da8Seschrock 
318275c9da8Seschrock 	return (P2ROUNDUP(len, 4));
319275c9da8Seschrock }
320275c9da8Seschrock 
321275c9da8Seschrock /*ARGSUSED*/
322275c9da8Seschrock static void *
323275c9da8Seschrock ses2_ucodeout_ctl_fill(ses_plugin_t *sp, void *data, size_t pagelen,
324275c9da8Seschrock     ses_node_t *np)
325275c9da8Seschrock {
326275c9da8Seschrock 	ses_snap_t *snap = ses_node_snapshot(np);
327275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
328275c9da8Seschrock 	ses2_ucode_ctl_page_impl_t *uip = data;
329275c9da8Seschrock 	uint64_t eid;
330275c9da8Seschrock 
331275c9da8Seschrock 	if (ses_node_type(np) != SES_NODE_ENCLOSURE) {
332275c9da8Seschrock 		(void) ses_error(ESES_BAD_TYPE,
333275c9da8Seschrock 		    "microcode download page only valid for enclosure "
334275c9da8Seschrock 		    "nodes");
335275c9da8Seschrock 		return (NULL);
336275c9da8Seschrock 	}
337275c9da8Seschrock 
338275c9da8Seschrock 	VERIFY(nvlist_lookup_uint64(props, SES_EN_PROP_EID, &eid) == 0);
339275c9da8Seschrock 
340275c9da8Seschrock 	SCSI_WRITE32(&uip->sucpi_generation_code,
341275c9da8Seschrock 	    ses_snap_generation(snap));
342275c9da8Seschrock 	uip->sucpi_subenclosure_identifier = eid;
343275c9da8Seschrock 
344275c9da8Seschrock 	return (data);
345275c9da8Seschrock }
346275c9da8Seschrock 
347275c9da8Seschrock /*ARGSUSED*/
348275c9da8Seschrock static size_t
349275c9da8Seschrock ses2_subnickout_len(uint_t nelem, int page, size_t datalen)
350275c9da8Seschrock {
351275c9da8Seschrock 	ASSERT(page == SES2_DIAGPAGE_SUBENCLOSURE_NICKNAME_CTL_STATUS);
352275c9da8Seschrock 
353275c9da8Seschrock 	return (sizeof (ses2_subnick_ctl_page_impl_t));
354275c9da8Seschrock }
355275c9da8Seschrock 
356275c9da8Seschrock ses_pagedesc_t ses2_pages[] = {
357275c9da8Seschrock {
358275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_SUPPORTED_PAGES,
359*ac88567aSHyon Kim 	.spd_req = SES_REQ_MANDATORY_ALL,
360275c9da8Seschrock 	.spd_gcoff = -1
361275c9da8Seschrock },
362275c9da8Seschrock {
363275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_CONFIG,
364*ac88567aSHyon Kim 	.spd_req = SES_REQ_MANDATORY_STANDARD,
365275c9da8Seschrock 	.spd_gcoff = offsetof(ses2_config_page_impl_t, scpi_generation_code)
366275c9da8Seschrock },
367275c9da8Seschrock {
368275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS,
369*ac88567aSHyon Kim 	.spd_req = SES_REQ_MANDATORY_STANDARD,
370275c9da8Seschrock 	.spd_index = ses2_status_index,
371275c9da8Seschrock 	.spd_gcoff = offsetof(ses2_status_page_impl_t, sspi_generation_code)
372275c9da8Seschrock },
373275c9da8Seschrock {
374275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_HELP_TEXT,
375*ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
376275c9da8Seschrock 	.spd_gcoff = -1
377275c9da8Seschrock },
378275c9da8Seschrock {
379275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_STRING_IO,
380*ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
381275c9da8Seschrock 	.spd_gcoff = -1
382275c9da8Seschrock },
383275c9da8Seschrock {
384275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_THRESHOLD_IO,
385275c9da8Seschrock 	.spd_index = ses2_threshold_index,
386*ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
387275c9da8Seschrock 	.spd_gcoff =
388275c9da8Seschrock 	    offsetof(ses2_threshold_in_page_impl_t, stipi_generation_code)
389275c9da8Seschrock },
390275c9da8Seschrock {
391275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_ELEMENT_DESC,
392275c9da8Seschrock 	.spd_index = ses2_element_index,
393*ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
394275c9da8Seschrock 	.spd_gcoff = offsetof(ses2_elem_desc_page_impl_t, sedpi_generation_code)
395275c9da8Seschrock },
396275c9da8Seschrock {
397275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_ADDL_ELEM_STATUS,
398275c9da8Seschrock 	.spd_index = ses2_aes_index,
399*ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
400275c9da8Seschrock 	.spd_gcoff = offsetof(ses2_aes_page_impl_t, sapi_generation_code)
401275c9da8Seschrock },
402275c9da8Seschrock {
403275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_SUBENCLOSURE_HELP_TEXT,
404*ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
405275c9da8Seschrock 	.spd_gcoff = offsetof(ses2_subhelp_page_impl_t, sspi_generation_code)
406275c9da8Seschrock },
407275c9da8Seschrock {
408275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_SUBENCLOSURE_STRING_IO,
409*ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
410275c9da8Seschrock 	.spd_gcoff =
411275c9da8Seschrock 	    offsetof(ses2_substring_in_page_impl_t, ssipi_generation_code)
412275c9da8Seschrock },
413275c9da8Seschrock {
414275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_SUPPORTED_SES_PAGES,
415*ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
416275c9da8Seschrock 	.spd_gcoff = -1
417275c9da8Seschrock },
418275c9da8Seschrock {
419275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_DL_MICROCODE_CTL_STATUS,
420*ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
421275c9da8Seschrock 	.spd_gcoff =
422275c9da8Seschrock 	    offsetof(ses2_ucode_status_page_impl_t, suspi_generation_code)
423275c9da8Seschrock },
424275c9da8Seschrock {
425275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_SUBENCLOSURE_NICKNAME_CTL_STATUS,
426*ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
427275c9da8Seschrock 	.spd_gcoff =
428275c9da8Seschrock 	    offsetof(ses2_subnick_status_page_impl_t, sspci_generation_code)
429275c9da8Seschrock },
430275c9da8Seschrock /* Control pages */
431275c9da8Seschrock {
432275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS,
433275c9da8Seschrock 	.spd_ctl_len = ses2_ctl_len,
434275c9da8Seschrock 	.spd_ctl_fill = ses2_ctl_fill,
435*ac88567aSHyon Kim 	.spd_req = SES_REQ_MANDATORY_STANDARD,
436275c9da8Seschrock 	.spd_gcoff = offsetof(ses2_control_page_impl_t, scpi_generation_code)
437275c9da8Seschrock },
438275c9da8Seschrock {
439275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_STRING_IO,
440275c9da8Seschrock 	.spd_ctl_len = ses2_stringout_len,
441*ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
442275c9da8Seschrock 	.spd_gcoff = -1
443275c9da8Seschrock },
444275c9da8Seschrock {
445275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_THRESHOLD_IO,
446275c9da8Seschrock 	.spd_ctl_len = ses2_threshout_len,
447275c9da8Seschrock 	.spd_ctl_fill = ses2_threshout_ctl_fill,
448*ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
449275c9da8Seschrock 	.spd_gcoff =
450275c9da8Seschrock 	    offsetof(ses2_threshold_out_page_impl_t, stopi_generation_code)
451275c9da8Seschrock },
452275c9da8Seschrock {
453275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_SUBENCLOSURE_STRING_IO,
454275c9da8Seschrock 	.spd_ctl_len = ses2_substrout_len,
455*ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
456275c9da8Seschrock 	.spd_gcoff =
457275c9da8Seschrock 	    offsetof(ses2_substring_out_page_impl_t, ssopi_generation_code)
458275c9da8Seschrock },
459275c9da8Seschrock {
460275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_DL_MICROCODE_CTL_STATUS,
461275c9da8Seschrock 	.spd_ctl_len = ses2_ucodeout_len,
462275c9da8Seschrock 	.spd_ctl_fill = ses2_ucodeout_ctl_fill,
463*ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
464275c9da8Seschrock 	.spd_gcoff =
465275c9da8Seschrock 	    offsetof(ses2_ucode_ctl_page_impl_t, sucpi_generation_code)
466275c9da8Seschrock },
467275c9da8Seschrock {
468275c9da8Seschrock 	.spd_pagenum = SES2_DIAGPAGE_SUBENCLOSURE_NICKNAME_CTL_STATUS,
469275c9da8Seschrock 	.spd_ctl_len = ses2_subnickout_len,
470*ac88567aSHyon Kim 	.spd_req = SES_REQ_OPTIONAL_STANDARD,
471275c9da8Seschrock 	.spd_gcoff =
472275c9da8Seschrock 	    offsetof(ses2_subnick_ctl_page_impl_t, sspci_generation_code)
473275c9da8Seschrock },
474275c9da8Seschrock {
475275c9da8Seschrock 	.spd_pagenum = -1,
476275c9da8Seschrock 	.spd_gcoff = -1
477275c9da8Seschrock }
478275c9da8Seschrock };
479