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