xref: /titanic_44/usr/src/cmd/picl/plugins/sun4v/pri/priplugin.c (revision 0398691684c2596072212e4ca9d7033ad7ccfa54)
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 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <pri.h>
30 #include "priplugin.h"
31 
32 #pragma init(priplugin_register)	/* place in .init section */
33 
34 picl_nodehdl_t	root_node;
35 static md_t	*mdp;
36 mde_cookie_t	rootnode;
37 
38 void priplugin_init(void);
39 void priplugin_fini(void);
40 static void
41 event_handler(const char *ename, const void *earg, size_t size, void *cookie);
42 static void *priplugin_main(void *);
43 
44 picld_plugin_reg_t priplugin_reg = {
45 	PICLD_PLUGIN_VERSION_1,
46 	PICLD_PLUGIN_CRITICAL,
47 	"pri_plugin",
48 	priplugin_init,
49 	priplugin_fini
50 };
51 
52 void
53 set_prop_info(ptree_propinfo_t *propinfo, int size, char *name, int type)
54 {
55 	propinfo->version = PICLD_PLUGIN_VERSION_1;
56 	propinfo->read = NULL;
57 	propinfo->write = NULL;
58 	propinfo->piclinfo.type = type;
59 	propinfo->piclinfo.accessmode = PICL_READ;
60 	propinfo->piclinfo.size = size;
61 	(void) strlcpy(propinfo->piclinfo.name, name,
62 	    sizeof (propinfo->piclinfo.name));
63 }
64 
65 boolean_t
66 prop_exists(picl_nodehdl_t node, char *name)
67 {
68 	int status;
69 	picl_prophdl_t proph;
70 
71 	status = ptree_get_prop_by_name(node, name, &proph);
72 	if (status == PICL_SUCCESS)
73 		return (B_TRUE);
74 	else
75 		return (B_FALSE);
76 }
77 
78 void
79 add_md_prop(picl_nodehdl_t node, int size, char *name, void* value, int type)
80 {
81 	ptree_propinfo_t propinfo;
82 	picl_prophdl_t proph;
83 
84 	if (!prop_exists(node, name)) {
85 		set_prop_info(&propinfo, size, name, type);
86 
87 		(void) ptree_create_and_add_prop(node, &propinfo,
88 		    value, &proph);
89 	}
90 }
91 
92 void
93 priplugin_init(void)
94 {
95 	int status;
96 
97 
98 	pri_debug(LOG_NOTICE, "priplugin: mem tree and io label thread "
99 	    "being created; callbacks being registered\n");
100 
101 	/*
102 	 * register event_handler for both "sysevent-device-added" and
103 	 * and for "sysevent-device-removed" PICL events
104 	 */
105 	(void) ptree_register_handler(PICLEVENT_SYSEVENT_DEVICE_ADDED,
106 	    event_handler, NULL);
107 	(void) ptree_register_handler(PICLEVENT_DR_AP_STATE_CHANGE,
108 	    event_handler, NULL);
109 
110 	if ((status = thr_create(NULL, NULL, priplugin_main, NULL, THR_BOUND,
111 	    NULL)) < 0) {
112 		pri_debug(LOG_NOTICE, "priplugin: can't create main thread: "
113 		    "%d\n", status);
114 		priplugin_fini();
115 	}
116 }
117 
118 /*ARGSUSED*/
119 static void *
120 priplugin_main(void *arg)
121 {
122 	int status;
123 	uint64_t tok;
124 
125 	if (pri_init() != 0) {
126 		pri_debug(LOG_NOTICE, "priplugin_main: pri_init failed\n");
127 		return (NULL);
128 	}
129 
130 	pri_debug(LOG_NOTICE, "priplugin: thread entered\n");
131 	status = ptree_get_root(&root_node);
132 	if (status != PICL_SUCCESS) {
133 		pri_debug(LOG_NOTICE, "priplugin: can't get picl root "
134 		    "node\n");
135 		priplugin_fini();
136 		return (NULL);
137 	}
138 
139 	for (tok = 0; mdp = pri_devinit(&tok, mdp); ) {
140 		rootnode = md_root_node(mdp);
141 
142 		pri_debug(LOG_NOTICE, "priplugin: have root picl and PRI "
143 		    "nodes\n");
144 
145 		status = ptree_walk_tree_by_class(root_node, "memory",
146 		    (void *) mdp, add_mem_prop);
147 		if (status != PICL_SUCCESS) {
148 			pri_debug(LOG_NOTICE, "pri: memory-segments walk "
149 			    "failed\n");
150 		} else
151 			pri_debug(LOG_NOTICE, "pri: success walking memory "
152 			    "node\n");
153 
154 		io_dev_addlabel(mdp);
155 	}
156 
157 	pri_debug(LOG_NOTICE, "priplugin: cannot init pri: " "%d\n", errno);
158 
159 	priplugin_fini();
160 
161 	/*NOTREACHED*/
162 	return (NULL);
163 }
164 
165 void
166 priplugin_fini(void)
167 {
168 	pri_devfini(mdp);
169 	/* unregister the event handler */
170 	(void) ptree_unregister_handler(PICLEVENT_SYSEVENT_DEVICE_ADDED,
171 	    event_handler, NULL);
172 	(void) ptree_unregister_handler(PICLEVENT_DR_AP_STATE_CHANGE,
173 	    event_handler, NULL);
174 }
175 
176 void
177 priplugin_register(void)
178 {
179 	picld_plugin_register(&priplugin_reg);
180 }
181 
182 /*
183  * Discovery event handler
184  * respond to the picl events:
185  *      PICLEVENT_SYSEVENT_DEVICE_ADDED
186  *      PICLEVENT_DR_AP_STATE_CHANGE
187  *
188  * We can't do much of anything fancy since the event data doesn't contain
189  * a nac for the device.  Nothing to do for remove - the devtree plug-in
190  * will have removed the node for us.  For add we have to go back and
191  * add labels again.
192  */
193 static void
194 event_handler(const char *ename, const void *earg, size_t size, void *cookie)
195 {
196 
197 	if ((strcmp(ename, PICLEVENT_SYSEVENT_DEVICE_ADDED) == 0) ||
198 	    (strcmp(ename, PICLEVENT_DR_AP_STATE_CHANGE) == 0)) {
199 		pri_debug(LOG_NOTICE, "pri: event_handler: caught event "
200 		    "%s; adding labels\n", ename);
201 		io_dev_addlabel(mdp);
202 	}
203 }
204 
205 /*VARARGS2*/
206 void
207 pri_debug(int level, char *fmt, ...)
208 {
209 #if (PRI_DEBUG != 0)
210 	va_list	ap;
211 
212 	va_start(ap, fmt);
213 	vsyslog(level, fmt, ap);
214 	va_end(ap);
215 #endif
216 }
217