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 /*
23275c9da8Seschrock * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24275c9da8Seschrock * Use is subject to license terms.
25275c9da8Seschrock */
26275c9da8Seschrock
27275c9da8Seschrock #include <string.h>
28275c9da8Seschrock #include <strings.h>
29275c9da8Seschrock
30275c9da8Seschrock #include <scsi/libses.h>
31275c9da8Seschrock #include <scsi/libses_plugin.h>
32275c9da8Seschrock
33275c9da8Seschrock #pragma pack(1)
34275c9da8Seschrock
35275c9da8Seschrock typedef struct ses_riverwalk_stringin {
36275c9da8Seschrock uint8_t rws_download_status;
37275c9da8Seschrock uint8_t rws_descriptor_start;
38275c9da8Seschrock uint16_t rws_descriptor_length;
39275c9da8Seschrock char rws_sim0_id[4];
40275c9da8Seschrock char rws_sim0_pn[15];
41275c9da8Seschrock char rws_sim0_sn[20];
42275c9da8Seschrock char rws_sim1_id[4];
43275c9da8Seschrock char rws_sim1_pn[15];
44275c9da8Seschrock char rws_sim1_sn[20];
45275c9da8Seschrock char rws_mid_id[4];
46275c9da8Seschrock char rws_mid_pn[15];
47275c9da8Seschrock char rws_mid_sn[20];
48275c9da8Seschrock char rws_ps0_id[4];
49275c9da8Seschrock char rws_ps0_pn[15];
50275c9da8Seschrock char rws_ps0_sn[20];
51275c9da8Seschrock char rws_ps1_id[4];
52275c9da8Seschrock char rws_ps1_pn[15];
53275c9da8Seschrock char rws_ps1_sn[20];
54275c9da8Seschrock char __reserved1[29];
55275c9da8Seschrock uint8_t rws_diag_start;
56275c9da8Seschrock uint8_t rws_eid;
57275c9da8Seschrock uint16_t rws_diag_length;
58275c9da8Seschrock uint8_t rws_sim_id;
59275c9da8Seschrock uint8_t rws_numport;
60275c9da8Seschrock uint16_t __reserved2;
61275c9da8Seschrock uint8_t rws_sasaddr[8];
62275c9da8Seschrock uint8_t rws_sys_sn[8];
63275c9da8Seschrock char rws_port0[16];
64275c9da8Seschrock char rws_port1[16];
65275c9da8Seschrock char rws_port2[16];
66275c9da8Seschrock } ses_riverwalk_stringin_t;
67275c9da8Seschrock
68275c9da8Seschrock #pragma pack()
69275c9da8Seschrock
70275c9da8Seschrock /*ARGSUSED*/
71275c9da8Seschrock static int
sun_riverwalk_parse_node(ses_plugin_t * sp,ses_node_t * np)72275c9da8Seschrock sun_riverwalk_parse_node(ses_plugin_t *sp, ses_node_t *np)
73275c9da8Seschrock {
74275c9da8Seschrock nvlist_t *props = ses_node_props(np);
75275c9da8Seschrock int nverr;
76275c9da8Seschrock ses_riverwalk_stringin_t *strp;
77275c9da8Seschrock char buf[32];
78275c9da8Seschrock uint64_t type, index;
79275c9da8Seschrock char *pn, *sn;
80275c9da8Seschrock ses_node_t *encp;
81275c9da8Seschrock nvlist_t *encprops;
82275c9da8Seschrock uint8_t *stringin;
83275c9da8Seschrock uint_t len;
84275c9da8Seschrock
85275c9da8Seschrock if (ses_node_type(np) != SES_NODE_ENCLOSURE &&
86275c9da8Seschrock ses_node_type(np) != SES_NODE_ELEMENT)
87275c9da8Seschrock return (0);
88275c9da8Seschrock
89275c9da8Seschrock /*
90275c9da8Seschrock * Find the containing enclosure node and extract the STRING IN
91275c9da8Seschrock * information.
92275c9da8Seschrock */
93275c9da8Seschrock for (encp = np; ses_node_type(encp) != SES_NODE_ENCLOSURE;
94275c9da8Seschrock encp = ses_node_parent(encp))
95275c9da8Seschrock ;
96275c9da8Seschrock
97275c9da8Seschrock encprops = ses_node_props(encp);
98275c9da8Seschrock if (nvlist_lookup_byte_array(encprops, SES_EN_PROP_STRING,
99275c9da8Seschrock &stringin, &len) != 0)
100275c9da8Seschrock return (0);
101275c9da8Seschrock
102275c9da8Seschrock if (len < sizeof (ses_riverwalk_stringin_t))
103275c9da8Seschrock return (0);
104275c9da8Seschrock
105275c9da8Seschrock strp = (ses_riverwalk_stringin_t *)stringin;
106275c9da8Seschrock
107275c9da8Seschrock switch (ses_node_type(np)) {
108275c9da8Seschrock case SES_NODE_ELEMENT:
109275c9da8Seschrock /*
110275c9da8Seschrock * We can get part and serial information for power supplies and
111275c9da8Seschrock * the SIM cards (ESC_ELECTRONICS elements).
112275c9da8Seschrock */
113275c9da8Seschrock VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_TYPE,
114275c9da8Seschrock &type) == 0);
115275c9da8Seschrock VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_CLASS_INDEX,
116275c9da8Seschrock &index) == 0);
117275c9da8Seschrock
118275c9da8Seschrock sn = pn = NULL;
119275c9da8Seschrock switch (type) {
120275c9da8Seschrock case SES_ET_POWER_SUPPLY:
121275c9da8Seschrock switch (index) {
122275c9da8Seschrock case 0:
123275c9da8Seschrock if (strncmp(strp->rws_ps0_id, "SPS0", 4) != 0)
124275c9da8Seschrock break;
125275c9da8Seschrock
126275c9da8Seschrock pn = strp->rws_ps0_pn;
127275c9da8Seschrock sn = strp->rws_ps0_sn;
128275c9da8Seschrock break;
129275c9da8Seschrock
130275c9da8Seschrock case 1:
131275c9da8Seschrock if (strncmp(strp->rws_ps1_id, "SPS1", 4) != 0)
132275c9da8Seschrock break;
133275c9da8Seschrock
134275c9da8Seschrock pn = strp->rws_ps1_pn;
135275c9da8Seschrock sn = strp->rws_ps1_sn;
136275c9da8Seschrock break;
137275c9da8Seschrock }
138275c9da8Seschrock break;
139275c9da8Seschrock
140275c9da8Seschrock case SES_ET_ESC_ELECTRONICS:
141275c9da8Seschrock switch (index) {
142275c9da8Seschrock case 0:
143275c9da8Seschrock if (strncmp(strp->rws_sim0_id, "SIM0", 4) != 0)
144275c9da8Seschrock break;
145275c9da8Seschrock
146275c9da8Seschrock pn = strp->rws_sim0_pn;
147275c9da8Seschrock sn = strp->rws_sim0_sn;
148275c9da8Seschrock break;
149275c9da8Seschrock
150275c9da8Seschrock case 1:
151275c9da8Seschrock if (strncmp(strp->rws_sim1_id, "SIM1", 4) != 0)
152275c9da8Seschrock break;
153275c9da8Seschrock
154275c9da8Seschrock pn = strp->rws_sim1_pn;
155275c9da8Seschrock sn = strp->rws_sim1_sn;
156275c9da8Seschrock break;
157275c9da8Seschrock }
158275c9da8Seschrock break;
159*a6e6969cSeschrock
160*a6e6969cSeschrock case SES_ET_COOLING:
161*a6e6969cSeschrock /*
162*a6e6969cSeschrock * The J4200 uses identical STRING IN data except that
163*a6e6969cSeschrock * the PSU part numbers are replaced with fan part
164*a6e6969cSeschrock * numbers. The power supply part and serial number
165*a6e6969cSeschrock * information are not available.
166*a6e6969cSeschrock */
167*a6e6969cSeschrock switch (index) {
168*a6e6969cSeschrock case 0:
169*a6e6969cSeschrock if (strncmp(strp->rws_ps0_id, "FAN0", 4) != 0)
170*a6e6969cSeschrock break;
171*a6e6969cSeschrock
172*a6e6969cSeschrock pn = strp->rws_ps0_pn;
173*a6e6969cSeschrock sn = strp->rws_ps0_sn;
174*a6e6969cSeschrock break;
175*a6e6969cSeschrock
176*a6e6969cSeschrock case 1:
177*a6e6969cSeschrock if (strncmp(strp->rws_ps1_id, "FAN1", 4) != 0)
178*a6e6969cSeschrock break;
179*a6e6969cSeschrock
180*a6e6969cSeschrock pn = strp->rws_ps1_pn;
181*a6e6969cSeschrock sn = strp->rws_ps1_sn;
182*a6e6969cSeschrock break;
183*a6e6969cSeschrock }
184*a6e6969cSeschrock break;
185*a6e6969cSeschrock
186275c9da8Seschrock }
187275c9da8Seschrock
188275c9da8Seschrock if (pn == NULL)
189275c9da8Seschrock return (0);
190275c9da8Seschrock
191275c9da8Seschrock if (pn[0] != '\0') {
192275c9da8Seschrock (void) bcopy(pn, buf, sizeof (strp->rws_ps0_pn));
193275c9da8Seschrock buf[sizeof (strp->rws_ps0_pn)] = '\0';
194275c9da8Seschrock SES_NV_ADD(string, nverr, props, LIBSES_PROP_PART,
195275c9da8Seschrock buf);
196275c9da8Seschrock }
197275c9da8Seschrock
198275c9da8Seschrock if (sn[0] != '\0') {
199275c9da8Seschrock (void) bcopy(sn, buf, sizeof (strp->rws_ps0_sn));
200275c9da8Seschrock buf[sizeof (strp->rws_ps0_sn)] = '\0';
201275c9da8Seschrock SES_NV_ADD(string, nverr, props, LIBSES_PROP_SERIAL,
202275c9da8Seschrock sn);
203275c9da8Seschrock }
204275c9da8Seschrock
205275c9da8Seschrock break;
206275c9da8Seschrock
207275c9da8Seschrock case SES_NODE_ENCLOSURE:
208275c9da8Seschrock /*
209275c9da8Seschrock * The chassis serial number is derived from the MID FRU
210275c9da8Seschrock * descriptor.
211275c9da8Seschrock */
212275c9da8Seschrock if (strncmp(strp->rws_mid_id, "MID ", 4) == 0 &&
213275c9da8Seschrock strp->rws_mid_sn[0] != '\0') {
214275c9da8Seschrock (void) bcopy(strp->rws_mid_sn, buf,
215275c9da8Seschrock sizeof (strp->rws_mid_sn));
216275c9da8Seschrock buf[sizeof (strp->rws_mid_sn)] = '\0';
217275c9da8Seschrock SES_NV_ADD(string, nverr, props, LIBSES_EN_PROP_CSN,
218275c9da8Seschrock buf);
219275c9da8Seschrock }
220275c9da8Seschrock
221275c9da8Seschrock break;
222275c9da8Seschrock }
223275c9da8Seschrock
224275c9da8Seschrock return (0);
225275c9da8Seschrock }
226275c9da8Seschrock
227275c9da8Seschrock int
_ses_init(ses_plugin_t * sp)228275c9da8Seschrock _ses_init(ses_plugin_t *sp)
229275c9da8Seschrock {
230275c9da8Seschrock ses_plugin_config_t config = {
231275c9da8Seschrock .spc_node_parse = sun_riverwalk_parse_node
232275c9da8Seschrock };
233275c9da8Seschrock
234275c9da8Seschrock return (ses_plugin_register(sp, LIBSES_PLUGIN_VERSION,
235275c9da8Seschrock &config) != 0);
236275c9da8Seschrock }
237