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 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * Open connections to the LDOM and Machine Description libraries used during 31 * enumeration. 32 */ 33 34 #include <sys/types.h> 35 #include <string.h> 36 #include <strings.h> 37 #include <sys/mdesc.h> 38 #include <sys/fm/ldom.h> 39 #include <sys/systeminfo.h> 40 41 #include "pi_impl.h" 42 43 static topo_mod_t *Pi_mod; 44 45 static void pi_free(void *, size_t); 46 static void * pi_alloc(size_t); 47 48 /* 49 * Initialize a connection to the LDOM machine description interface. 50 */ 51 int 52 pi_ldompri_open(topo_mod_t *mod, pi_enum_t *pip) 53 { 54 if (mod == NULL || pip == NULL) { 55 return (-1); 56 } 57 58 /* 59 * Store the module pointer for this session. This file-global 60 * is used by the allocators called by libldom and libmdesc. 61 */ 62 Pi_mod = mod; 63 64 /* Initialize the LDOM connection */ 65 pip->ldomp = ldom_init(pi_alloc, pi_free); 66 if (pip->ldomp == NULL) { 67 topo_mod_dprintf(mod, 68 "sun4vpi failed to initialize LDOM layer.\n"); 69 Pi_mod = NULL; 70 return (-1); 71 } 72 73 /* Initialize the machine description layer for this ldom instance */ 74 pip->ldom_bufsize = ldom_get_core_md(pip->ldomp, &(pip->ldom_bufp)); 75 if (pip->ldom_bufsize < 1) { 76 topo_mod_dprintf(mod, "ldom_get_core_md error: bufsize = %d\n", 77 pip->ldom_bufsize); 78 ldom_fini(pip->ldomp); 79 Pi_mod = NULL; 80 return (-1); 81 } 82 83 /* Initialize the machine description internal layer */ 84 pip->mdp = md_init_intern(pip->ldom_bufp, pi_alloc, pi_free); 85 if (pip->mdp == NULL || 86 (pip->md_nodes = md_node_count(pip->mdp)) < 1) { 87 topo_mod_dprintf(mod, "md_init_intern error\n"); 88 pi_free(pip->ldom_bufp, pip->ldom_bufsize); 89 ldom_fini(pip->ldomp); 90 Pi_mod = NULL; 91 return (-1); 92 } 93 94 return (0); 95 } 96 97 98 /* ARGSUSED */ 99 void 100 pi_ldompri_close(topo_mod_t *mod, pi_enum_t *pip) 101 { 102 if (pip == NULL) { 103 return; 104 } 105 106 /* Close the machine description connection */ 107 (void) md_fini(pip->mdp); 108 109 /* Close the connection to the LDOM layer */ 110 ldom_fini(pip->ldomp); 111 112 /* Free the ldom connection data */ 113 pi_free(pip->ldom_bufp, pip->ldom_bufsize); 114 115 /* Reset the file-global module pointer */ 116 Pi_mod = NULL; 117 } 118 119 120 static void * 121 pi_alloc(size_t size) 122 { 123 if (Pi_mod == NULL) { 124 /* Cannot allocate memory without a module pointer */ 125 return (NULL); 126 } 127 return (topo_mod_alloc(Pi_mod, size)); 128 } 129 130 131 static void 132 pi_free(void *buf, size_t size) 133 { 134 if (Pi_mod == NULL) { 135 /* Cannot free memory without a module pointer */ 136 return; 137 } 138 topo_mod_free(Pi_mod, buf, size); 139 } 140