xref: /titanic_44/usr/src/cmd/picl/plugins/sun4v/mdesc/mdescplugin.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 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 /*
30  * The MDESC picl plugin serves 2 different functionalities.
31  * --The first is to look up certain CPU properties in the MDESC an to add
32  * these properties in the already created CPU PICL nodes in the /platform
33  * section of the tree.
34  * --The second functionality is to create a /disk_discovery section of the
35  * PICL tree which will have a disk node created for each disk node in the
36  * machine description.
37  */
38 
39 #include "mdescplugin.h"
40 
41 #pragma init(mdescplugin_register)	/* place in .init section */
42 
43 picl_nodehdl_t	root_node;
44 md_t		*mdp;
45 mde_cookie_t	rootnode;
46 
47 void mdescplugin_init(void);
48 void mdescplugin_fini(void);
49 
50 extern int add_cpu_prop(picl_nodehdl_t node, void *args);
51 extern int disk_discovery(void);
52 extern md_t *mdesc_devinit(void);
53 
54 picld_plugin_reg_t mdescplugin_reg = {
55 	PICLD_PLUGIN_VERSION_1,
56 	PICLD_PLUGIN_CRITICAL,
57 	"mdesc_plugin",
58 	mdescplugin_init,
59 	mdescplugin_fini
60 };
61 
62 #define	DISK_FOUND 0x00
63 #define	DISK_NOT_FOUND 0x01
64 
65 typedef struct disk_lookup {
66 	char *path;
67 	picl_nodehdl_t disk;
68 	int result;
69 } disk_lookup_t;
70 
71 int
72 find_disk(picl_nodehdl_t node, void *args)
73 {
74 	disk_lookup_t *lookup  = (disk_lookup_t *)args;
75 	int status;
76 	char path[PICL_PROPNAMELEN_MAX];
77 
78 	status = ptree_get_propval_by_name(node, "Path", (void *)&path,
79 	    PICL_PROPNAMELEN_MAX);
80 	if (status != PICL_SUCCESS) {
81 		return (PICL_WALK_CONTINUE);
82 	}
83 
84 	if (strcmp(path, lookup->path) == 0) {
85 		lookup->disk = node;
86 		lookup->result = DISK_FOUND;
87 		return (PICL_WALK_TERMINATE);
88 	}
89 
90 	return (PICL_WALK_CONTINUE);
91 }
92 
93 /*
94  * Discovery event handler
95  * respond to the picl events:
96  *      PICLEVENT_SYSEVENT_DEVICE_ADDED
97  *      PICLEVENT_SYSEVENT_DEVICE_REMOVED
98  */
99 static void
100 dsc_handler(const char *ename, const void *earg, size_t size, void *cookie)
101 {
102 	nvlist_t	*nvlp = NULL;
103 	char		*path;
104 	disk_lookup_t	lookup;
105 	int		status;
106 
107 	/*
108 	 * retrieve the device's physical path from the event arg
109 	 * and determine which disk (if any) we are working with
110 	 */
111 	if (nvlist_unpack((char *)earg, size, &nvlp, NULL))
112 		return;
113 	if (nvlist_lookup_string(nvlp, "devfs-path", &path))
114 		return;
115 
116 	lookup.path = strdup(path);
117 	lookup.disk = NULL;
118 	lookup.result = DISK_NOT_FOUND;
119 
120 	status = ptree_walk_tree_by_class(root_node, "disk", (void *)&lookup,
121 	    find_disk);
122 	if (status != PICL_SUCCESS) {
123 		return;
124 	}
125 
126 	if (lookup.result == DISK_FOUND) {
127 		if (strcmp(ename, PICLEVENT_SYSEVENT_DEVICE_ADDED) == 0)
128 			ptree_update_propval_by_name(lookup.disk, "State",
129 			    (void *)strdup(CONFIGURED), PICL_PROPNAMELEN_MAX);
130 		else if (strcmp(ename, PICLEVENT_SYSEVENT_DEVICE_REMOVED) == 0)
131 			ptree_update_propval_by_name(lookup.disk, "State",
132 			    (void *)strdup(UNCONFIGURED), PICL_PROPNAMELEN_MAX);
133 	}
134 
135 	nvlist_free(nvlp);
136 }
137 
138 void
139 mdescplugin_init(void)
140 {
141 	int		status;
142 
143 	status = ptree_get_root(&root_node);
144 	if (status != PICL_SUCCESS) {
145 		return;
146 	}
147 
148 	mdp = mdesc_devinit();
149 	if (mdp == NULL)
150 		return;
151 
152 	rootnode = md_root_node(mdp);
153 
154 	/*
155 	 * This is the start of the CPU property augmentation code.
156 	 * add_cpu_prop and the rest of the CPU code lives in cpu_prop_update.c
157 	 */
158 	status = ptree_walk_tree_by_class(root_node, "cpu", NULL, add_cpu_prop);
159 	if (status != PICL_SUCCESS) {
160 		return;
161 	}
162 
163 	(void) disk_discovery();
164 
165 	/*
166 	 * register dsc_handler for both "sysevent-device-added" and
167 	 * and for "sysevent-device-removed" PICL events
168 	 */
169 	(void) ptree_register_handler(PICLEVENT_SYSEVENT_DEVICE_ADDED,
170 	    dsc_handler, NULL);
171 	(void) ptree_register_handler(PICLEVENT_SYSEVENT_DEVICE_REMOVED,
172 	    dsc_handler, NULL);
173 
174 	(void) md_fini(mdp);
175 }
176 
177 void
178 mdescplugin_fini(void)
179 {
180 	/* unregister the event handler */
181 	(void) ptree_unregister_handler(PICLEVENT_SYSEVENT_DEVICE_ADDED,
182 	    dsc_handler, NULL);
183 	(void) ptree_unregister_handler(PICLEVENT_SYSEVENT_DEVICE_REMOVED,
184 	    dsc_handler, NULL);
185 }
186 
187 void
188 mdescplugin_register(void)
189 {
190 	picld_plugin_register(&mdescplugin_reg);
191 }
192