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