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 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Create a generic topology node for a given PRI node. 29 */ 30 #include <sys/types.h> 31 #include <strings.h> 32 #include <sys/fm/protocol.h> 33 #include <fm/topo_mod.h> 34 #include <fm/topo_hc.h> 35 #include "pi_impl.h" 36 37 #define _ENUM_NAME "enum_generic" 38 39 /* Topo methods definitions */ 40 extern nvlist_t *pi_meths; 41 42 int 43 pi_enum_generic(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node, 44 topo_instance_t inst, tnode_t *t_parent, const char *hc_name, 45 tnode_t **t_node) 46 { 47 int result; 48 49 /* 50 * For a generic node that is not a top-level node, we use the 51 * same parent topology node to generate the FMRI as well as 52 * to bind the new node. 53 */ 54 result = pi_enum_generic_impl(mod, mdp, mde_node, inst, t_parent, 55 t_parent, hc_name, _ENUM_NAME, t_node, 0); 56 57 return (result); 58 } 59 60 61 /* 62 * Create a generic topo node based on the PRI information in the machine 63 * description information. 64 */ 65 int 66 pi_enum_generic_impl(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node, 67 topo_instance_t inst, tnode_t *t_bindparent, tnode_t *t_fmriparent, 68 const char *hc_name, const char *enum_name, tnode_t **t_node, int flag) 69 { 70 nvlist_t *fmri; 71 nvlist_t *auth; 72 uint64_t maddr; 73 char *serial = NULL; 74 75 topo_mod_dprintf(mod, "%s adding entry for node_0x%llx type %s\n", 76 enum_name, (uint64_t)mde_node, hc_name); 77 78 if (t_bindparent == NULL) { 79 topo_mod_dprintf(mod, 80 "%s called with NULL parent for node_0x%llx type %s\n", 81 enum_name, (uint64_t)mde_node, hc_name); 82 return (-1); 83 } 84 85 /* Create the FMRI for this node */ 86 auth = topo_mod_auth(mod, t_bindparent); 87 if (flag & SUN4VPI_ENUM_ADD_SERIAL) 88 serial = pi_get_serial(mod, mdp, mde_node); 89 90 fmri = topo_mod_hcfmri(mod, t_fmriparent, FM_HC_SCHEME_VERSION, hc_name, 91 inst, NULL, auth, NULL, NULL, serial); 92 93 if (serial != NULL) 94 topo_mod_strfree(mod, serial); 95 nvlist_free(auth); 96 97 if (fmri == NULL) { 98 topo_mod_dprintf(mod, 99 "%s failed to create fmri node_0x%llx: %s\n", enum_name, 100 (uint64_t)mde_node, topo_strerror(topo_mod_errno(mod))); 101 return (-1); 102 } 103 104 /* Bind this node to the parent */ 105 *t_node = pi_node_bind(mod, mdp, mde_node, t_bindparent, hc_name, inst, 106 fmri); 107 nvlist_free(fmri); 108 if (*t_node == NULL) { 109 topo_mod_dprintf(mod, 110 "%s failed to bind node_0x%llx instance %d: %s\n", 111 enum_name, (uint64_t)mde_node, (uint32_t)inst, 112 topo_strerror(topo_mod_errno(mod))); 113 return (-1); 114 } 115 116 /* Register topo methods that match hc_name */ 117 if (nvlist_lookup_uint64(pi_meths, hc_name, &maddr) == 0 && 118 topo_method_register(mod, *t_node, 119 (topo_method_t *)(uintptr_t)maddr) != 0) 120 topo_mod_dprintf(mod, 121 "failed to register methods for node_0x%llx type %s\n", 122 (uint64_t)mde_node, hc_name); 123 124 topo_mod_dprintf(mod, "%s added node_0x%llx type %s\n", 125 enum_name, (uint64_t)mde_node, hc_name); 126 127 return (0); 128 } 129