17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51ae08745Sheppo * Common Development and Distribution License (the "License").
61ae08745Sheppo * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
211ae08745Sheppo
227c478bd9Sstevel@tonic-gate /*
23*c69cf0c1SMichael Bergknoff * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate /*
287c478bd9Sstevel@tonic-gate * The MDESC picl plugin serves 2 different functionalities.
297c478bd9Sstevel@tonic-gate * --The first is to look up certain CPU properties in the MDESC an to add
307c478bd9Sstevel@tonic-gate * these properties in the already created CPU PICL nodes in the /platform
317c478bd9Sstevel@tonic-gate * section of the tree.
327c478bd9Sstevel@tonic-gate * --The second functionality is to create a /disk_discovery section of the
337c478bd9Sstevel@tonic-gate * PICL tree which will have a disk node created for each disk node in the
347c478bd9Sstevel@tonic-gate * machine description.
357c478bd9Sstevel@tonic-gate */
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate #include "mdescplugin.h"
385e3e415aSfw157321 #include <libnvpair.h>
397c478bd9Sstevel@tonic-gate
407c478bd9Sstevel@tonic-gate #pragma init(mdescplugin_register) /* place in .init section */
417c478bd9Sstevel@tonic-gate
427c478bd9Sstevel@tonic-gate picl_nodehdl_t root_node;
437c478bd9Sstevel@tonic-gate md_t *mdp;
447c478bd9Sstevel@tonic-gate mde_cookie_t rootnode;
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate void mdescplugin_init(void);
477c478bd9Sstevel@tonic-gate void mdescplugin_fini(void);
48*c69cf0c1SMichael Bergknoff static void signal_devtree(void);
497c478bd9Sstevel@tonic-gate
507c478bd9Sstevel@tonic-gate extern int add_cpu_prop(picl_nodehdl_t node, void *args);
517c478bd9Sstevel@tonic-gate extern int disk_discovery(void);
527c478bd9Sstevel@tonic-gate extern md_t *mdesc_devinit(void);
531ae08745Sheppo extern void mdesc_devfini(md_t *mdp);
541ae08745Sheppo extern int update_devices(char *dev, int op);
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate picld_plugin_reg_t mdescplugin_reg = {
577c478bd9Sstevel@tonic-gate PICLD_PLUGIN_VERSION_1,
587c478bd9Sstevel@tonic-gate PICLD_PLUGIN_CRITICAL,
597c478bd9Sstevel@tonic-gate "mdesc_plugin",
607c478bd9Sstevel@tonic-gate mdescplugin_init,
617c478bd9Sstevel@tonic-gate mdescplugin_fini
627c478bd9Sstevel@tonic-gate };
637c478bd9Sstevel@tonic-gate
647c478bd9Sstevel@tonic-gate #define DISK_FOUND 0x00
657c478bd9Sstevel@tonic-gate #define DISK_NOT_FOUND 0x01
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate typedef struct disk_lookup {
687c478bd9Sstevel@tonic-gate char *path;
697c478bd9Sstevel@tonic-gate picl_nodehdl_t disk;
707c478bd9Sstevel@tonic-gate int result;
717c478bd9Sstevel@tonic-gate } disk_lookup_t;
727c478bd9Sstevel@tonic-gate
737c478bd9Sstevel@tonic-gate int
find_disk(picl_nodehdl_t node,void * args)747c478bd9Sstevel@tonic-gate find_disk(picl_nodehdl_t node, void *args)
757c478bd9Sstevel@tonic-gate {
767c478bd9Sstevel@tonic-gate disk_lookup_t *lookup = (disk_lookup_t *)args;
777c478bd9Sstevel@tonic-gate int status;
787c478bd9Sstevel@tonic-gate char path[PICL_PROPNAMELEN_MAX];
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate status = ptree_get_propval_by_name(node, "Path", (void *)&path,
817c478bd9Sstevel@tonic-gate PICL_PROPNAMELEN_MAX);
827c478bd9Sstevel@tonic-gate if (status != PICL_SUCCESS) {
837c478bd9Sstevel@tonic-gate return (PICL_WALK_CONTINUE);
847c478bd9Sstevel@tonic-gate }
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate if (strcmp(path, lookup->path) == 0) {
877c478bd9Sstevel@tonic-gate lookup->disk = node;
887c478bd9Sstevel@tonic-gate lookup->result = DISK_FOUND;
897c478bd9Sstevel@tonic-gate return (PICL_WALK_TERMINATE);
907c478bd9Sstevel@tonic-gate }
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate return (PICL_WALK_CONTINUE);
937c478bd9Sstevel@tonic-gate }
947c478bd9Sstevel@tonic-gate
957c478bd9Sstevel@tonic-gate /*
961ae08745Sheppo * DR event handler
971ae08745Sheppo * respond to the picl events:
981ae08745Sheppo * PICLEVENT_DR_AP_STATE_CHANGE
991ae08745Sheppo */
1001ae08745Sheppo static void
dr_handler(const char * ename,const void * earg,size_t size,void * cookie)1011ae08745Sheppo dr_handler(const char *ename, const void *earg, size_t size, void *cookie)
1021ae08745Sheppo {
1031ae08745Sheppo nvlist_t *nvlp = NULL;
1041ae08745Sheppo char *dtype;
1051ae08745Sheppo char *ap_id;
1061ae08745Sheppo char *hint;
1071ae08745Sheppo
1081ae08745Sheppo
1091ae08745Sheppo if (strcmp(ename, PICLEVENT_DR_AP_STATE_CHANGE) != 0) {
1101ae08745Sheppo return;
1111ae08745Sheppo }
1121ae08745Sheppo
1131ae08745Sheppo if (nvlist_unpack((char *)earg, size, &nvlp, NULL)) {
1141ae08745Sheppo return;
1151ae08745Sheppo }
1161ae08745Sheppo
1171ae08745Sheppo if (nvlist_lookup_string(nvlp, PICLEVENTARG_DATA_TYPE, &dtype)) {
1181ae08745Sheppo nvlist_free(nvlp);
1191ae08745Sheppo return;
1201ae08745Sheppo }
1211ae08745Sheppo
1221ae08745Sheppo if (strcmp(dtype, PICLEVENTARG_PICLEVENT_DATA) != 0) {
1231ae08745Sheppo nvlist_free(nvlp);
1241ae08745Sheppo return;
1251ae08745Sheppo }
1261ae08745Sheppo
1271ae08745Sheppo if (nvlist_lookup_string(nvlp, PICLEVENTARG_AP_ID, &ap_id)) {
1281ae08745Sheppo nvlist_free(nvlp);
1291ae08745Sheppo return;
1301ae08745Sheppo }
1311ae08745Sheppo
1321ae08745Sheppo if (nvlist_lookup_string(nvlp, PICLEVENTARG_HINT, &hint)) {
1331ae08745Sheppo nvlist_free(nvlp);
1341ae08745Sheppo return;
1351ae08745Sheppo }
1361ae08745Sheppo
1371ae08745Sheppo mdp = mdesc_devinit();
1381ae08745Sheppo if (mdp == NULL) {
1391ae08745Sheppo nvlist_free(nvlp);
1401ae08745Sheppo return;
1411ae08745Sheppo }
1421ae08745Sheppo
1431ae08745Sheppo rootnode = md_root_node(mdp);
1441ae08745Sheppo
1451ae08745Sheppo if (strcmp(hint, DR_HINT_INSERT) == 0)
1461ae08745Sheppo (void) update_devices(ap_id, DEV_ADD);
1471ae08745Sheppo else if (strcmp(hint, DR_HINT_REMOVE) == 0)
1481ae08745Sheppo (void) update_devices(ap_id, DEV_REMOVE);
1491ae08745Sheppo
1501ae08745Sheppo mdesc_devfini(mdp);
1511ae08745Sheppo nvlist_free(nvlp);
152*c69cf0c1SMichael Bergknoff
153*c69cf0c1SMichael Bergknoff /*
154*c69cf0c1SMichael Bergknoff * Signal the devtree plugin to add more cpu properties.
155*c69cf0c1SMichael Bergknoff */
156*c69cf0c1SMichael Bergknoff signal_devtree();
1571ae08745Sheppo }
1581ae08745Sheppo
1591ae08745Sheppo /*
1607c478bd9Sstevel@tonic-gate * Discovery event handler
1617c478bd9Sstevel@tonic-gate * respond to the picl events:
1627c478bd9Sstevel@tonic-gate * PICLEVENT_SYSEVENT_DEVICE_ADDED
1637c478bd9Sstevel@tonic-gate * PICLEVENT_SYSEVENT_DEVICE_REMOVED
1647c478bd9Sstevel@tonic-gate */
1657c478bd9Sstevel@tonic-gate static void
dsc_handler(const char * ename,const void * earg,size_t size,void * cookie)1667c478bd9Sstevel@tonic-gate dsc_handler(const char *ename, const void *earg, size_t size, void *cookie)
1677c478bd9Sstevel@tonic-gate {
1687c478bd9Sstevel@tonic-gate nvlist_t *nvlp = NULL;
1697c478bd9Sstevel@tonic-gate char *path;
1707c478bd9Sstevel@tonic-gate disk_lookup_t lookup;
1717c478bd9Sstevel@tonic-gate int status;
1727c478bd9Sstevel@tonic-gate
1737c478bd9Sstevel@tonic-gate /*
1747c478bd9Sstevel@tonic-gate * retrieve the device's physical path from the event arg
1757c478bd9Sstevel@tonic-gate * and determine which disk (if any) we are working with
1767c478bd9Sstevel@tonic-gate */
1777c478bd9Sstevel@tonic-gate if (nvlist_unpack((char *)earg, size, &nvlp, NULL))
1787c478bd9Sstevel@tonic-gate return;
1797c478bd9Sstevel@tonic-gate if (nvlist_lookup_string(nvlp, "devfs-path", &path))
1807c478bd9Sstevel@tonic-gate return;
1817c478bd9Sstevel@tonic-gate
1827c478bd9Sstevel@tonic-gate lookup.path = strdup(path);
1837c478bd9Sstevel@tonic-gate lookup.disk = NULL;
1847c478bd9Sstevel@tonic-gate lookup.result = DISK_NOT_FOUND;
1857c478bd9Sstevel@tonic-gate
1867c478bd9Sstevel@tonic-gate status = ptree_walk_tree_by_class(root_node, "disk", (void *)&lookup,
1877c478bd9Sstevel@tonic-gate find_disk);
1887c478bd9Sstevel@tonic-gate if (status != PICL_SUCCESS) {
1897c478bd9Sstevel@tonic-gate return;
1907c478bd9Sstevel@tonic-gate }
1917c478bd9Sstevel@tonic-gate
1927c478bd9Sstevel@tonic-gate if (lookup.result == DISK_FOUND) {
1937c478bd9Sstevel@tonic-gate if (strcmp(ename, PICLEVENT_SYSEVENT_DEVICE_ADDED) == 0)
1947c478bd9Sstevel@tonic-gate ptree_update_propval_by_name(lookup.disk, "State",
1957c478bd9Sstevel@tonic-gate (void *)strdup(CONFIGURED), PICL_PROPNAMELEN_MAX);
1967c478bd9Sstevel@tonic-gate else if (strcmp(ename, PICLEVENT_SYSEVENT_DEVICE_REMOVED) == 0)
1977c478bd9Sstevel@tonic-gate ptree_update_propval_by_name(lookup.disk, "State",
1987c478bd9Sstevel@tonic-gate (void *)strdup(UNCONFIGURED), PICL_PROPNAMELEN_MAX);
1997c478bd9Sstevel@tonic-gate }
2007c478bd9Sstevel@tonic-gate
2017c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
2027c478bd9Sstevel@tonic-gate }
2037c478bd9Sstevel@tonic-gate
2045e3e415aSfw157321 /*ARGSUSED*/
2055e3e415aSfw157321 static void
mdesc_ev_completion_handler(char * ename,void * earg,size_t size)2065e3e415aSfw157321 mdesc_ev_completion_handler(char *ename, void *earg, size_t size)
2075e3e415aSfw157321 {
2085e3e415aSfw157321 free(earg);
2095e3e415aSfw157321 }
2105e3e415aSfw157321
2115e3e415aSfw157321 static void
signal_devtree(void)2125e3e415aSfw157321 signal_devtree(void)
2135e3e415aSfw157321 {
2145e3e415aSfw157321 nvlist_t *nvl;
2155e3e415aSfw157321 char *packed_nvl;
2165e3e415aSfw157321 size_t nvl_size;
2175e3e415aSfw157321 int status;
2185e3e415aSfw157321
2195e3e415aSfw157321 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME_TYPE, NULL) != 0)
2205e3e415aSfw157321 return;
2215e3e415aSfw157321
2225e3e415aSfw157321 /*
2235e3e415aSfw157321 * Right now (Aug. 2007) snowbird is the only other platform
2245e3e415aSfw157321 * which uses this event. Since that's a sun4u platform and
2255e3e415aSfw157321 * this is sun4v we do not have to worry about possible confusion
2265e3e415aSfw157321 * or interference between the two by grabbing this event for
2275e3e415aSfw157321 * our own use here. This event is consumed by the devtree
2285e3e415aSfw157321 * plug-in. The event signals the plug-in to re-run its
2295e3e415aSfw157321 * cpu initialization function, which will cause it to add
2305e3e415aSfw157321 * additional information to the cpu devtree nodes (particularly,
2315e3e415aSfw157321 * the administrative state of the cpus.)
2325e3e415aSfw157321 */
2335e3e415aSfw157321 if (nvlist_add_string(nvl, PICLEVENTARG_EVENT_NAME,
2345e3e415aSfw157321 PICLEVENT_CPU_STATE_CHANGE) != 0) {
2355e3e415aSfw157321 free(nvl);
2365e3e415aSfw157321 return;
2375e3e415aSfw157321 }
2385e3e415aSfw157321
2395e3e415aSfw157321 /*
2405e3e415aSfw157321 * The devtree plug-in needs to see a devfs path argument for
2415e3e415aSfw157321 * any event it considers. We supply one here which is essentially
2425e3e415aSfw157321 * a dummy since it is not processed by the devtree plug-in for
2435e3e415aSfw157321 * this event.
2445e3e415aSfw157321 */
2455e3e415aSfw157321 if (nvlist_add_string(nvl, PICLEVENTARG_DEVFS_PATH, "/cpu") != 0) {
2465e3e415aSfw157321 free(nvl);
2475e3e415aSfw157321 return;
2485e3e415aSfw157321 }
249f2a592f8Sfw157321 packed_nvl = NULL;
2505e3e415aSfw157321 if (nvlist_pack(nvl, &packed_nvl, &nvl_size, NV_ENCODE_NATIVE,
251f2a592f8Sfw157321 0) != 0) {
2525e3e415aSfw157321 free(nvl);
2535e3e415aSfw157321 return;
2545e3e415aSfw157321 }
2555e3e415aSfw157321 if ((status = ptree_post_event(PICLEVENT_CPU_STATE_CHANGE,
2565e3e415aSfw157321 packed_nvl, nvl_size, mdesc_ev_completion_handler)) !=
2575e3e415aSfw157321 PICL_SUCCESS) {
2585e3e415aSfw157321 free(nvl);
2595e3e415aSfw157321 syslog(LOG_WARNING,
2605e3e415aSfw157321 "signal_devtree: can't post cpu event: %d\n", status);
2615e3e415aSfw157321 }
2625e3e415aSfw157321 }
2635e3e415aSfw157321
2647c478bd9Sstevel@tonic-gate void
mdescplugin_init(void)2657c478bd9Sstevel@tonic-gate mdescplugin_init(void)
2667c478bd9Sstevel@tonic-gate {
2677c478bd9Sstevel@tonic-gate int status;
2687c478bd9Sstevel@tonic-gate
2697c478bd9Sstevel@tonic-gate status = ptree_get_root(&root_node);
2707c478bd9Sstevel@tonic-gate if (status != PICL_SUCCESS) {
2717c478bd9Sstevel@tonic-gate return;
2727c478bd9Sstevel@tonic-gate }
2737c478bd9Sstevel@tonic-gate
2747c478bd9Sstevel@tonic-gate mdp = mdesc_devinit();
2757c478bd9Sstevel@tonic-gate if (mdp == NULL)
2767c478bd9Sstevel@tonic-gate return;
2777c478bd9Sstevel@tonic-gate
278535c87f8Smb158278 /*
279535c87f8Smb158278 * update the cpu configuration in case the snapshot cache used by the
280535c87f8Smb158278 * devtree plugin is out of date.
281535c87f8Smb158278 */
282535c87f8Smb158278 (void) update_devices(OBP_CPU, DEV_ADD);
283535c87f8Smb158278 (void) update_devices(OBP_CPU, DEV_REMOVE);
284535c87f8Smb158278
2857c478bd9Sstevel@tonic-gate rootnode = md_root_node(mdp);
2867c478bd9Sstevel@tonic-gate
2877c478bd9Sstevel@tonic-gate /*
2887c478bd9Sstevel@tonic-gate * This is the start of the CPU property augmentation code.
2897c478bd9Sstevel@tonic-gate * add_cpu_prop and the rest of the CPU code lives in cpu_prop_update.c
2907c478bd9Sstevel@tonic-gate */
2917c478bd9Sstevel@tonic-gate status = ptree_walk_tree_by_class(root_node, "cpu", NULL, add_cpu_prop);
2927c478bd9Sstevel@tonic-gate if (status != PICL_SUCCESS) {
2937c478bd9Sstevel@tonic-gate return;
2947c478bd9Sstevel@tonic-gate }
2957c478bd9Sstevel@tonic-gate
2965e3e415aSfw157321 signal_devtree();
2975e3e415aSfw157321
2987c478bd9Sstevel@tonic-gate (void) disk_discovery();
2997c478bd9Sstevel@tonic-gate
3007c478bd9Sstevel@tonic-gate /*
3017c478bd9Sstevel@tonic-gate * register dsc_handler for both "sysevent-device-added" and
3027c478bd9Sstevel@tonic-gate * and for "sysevent-device-removed" PICL events
3037c478bd9Sstevel@tonic-gate */
3047c478bd9Sstevel@tonic-gate (void) ptree_register_handler(PICLEVENT_SYSEVENT_DEVICE_ADDED,
3057c478bd9Sstevel@tonic-gate dsc_handler, NULL);
3067c478bd9Sstevel@tonic-gate (void) ptree_register_handler(PICLEVENT_SYSEVENT_DEVICE_REMOVED,
3077c478bd9Sstevel@tonic-gate dsc_handler, NULL);
3081ae08745Sheppo (void) ptree_register_handler(PICLEVENT_DR_AP_STATE_CHANGE,
3091ae08745Sheppo dr_handler, NULL);
3107c478bd9Sstevel@tonic-gate
3111ae08745Sheppo mdesc_devfini(mdp);
3127c478bd9Sstevel@tonic-gate }
3137c478bd9Sstevel@tonic-gate
3147c478bd9Sstevel@tonic-gate void
mdescplugin_fini(void)3157c478bd9Sstevel@tonic-gate mdescplugin_fini(void)
3167c478bd9Sstevel@tonic-gate {
3177c478bd9Sstevel@tonic-gate /* unregister the event handler */
3187c478bd9Sstevel@tonic-gate (void) ptree_unregister_handler(PICLEVENT_SYSEVENT_DEVICE_ADDED,
3197c478bd9Sstevel@tonic-gate dsc_handler, NULL);
3207c478bd9Sstevel@tonic-gate (void) ptree_unregister_handler(PICLEVENT_SYSEVENT_DEVICE_REMOVED,
3217c478bd9Sstevel@tonic-gate dsc_handler, NULL);
3221ae08745Sheppo (void) ptree_unregister_handler(PICLEVENT_DR_AP_STATE_CHANGE,
3231ae08745Sheppo dr_handler, NULL);
3247c478bd9Sstevel@tonic-gate }
3257c478bd9Sstevel@tonic-gate
3267c478bd9Sstevel@tonic-gate void
mdescplugin_register(void)3277c478bd9Sstevel@tonic-gate mdescplugin_register(void)
3287c478bd9Sstevel@tonic-gate {
3297c478bd9Sstevel@tonic-gate picld_plugin_register(&mdescplugin_reg);
3307c478bd9Sstevel@tonic-gate }
331