1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright (c) 2017, Joyent, Inc. 14 */ 15 16 #include <sys/fm/protocol.h> 17 #include <fm/topo_mod.h> 18 #include <fm/topo_list.h> 19 #include <fm/topo_method.h> 20 21 #include <topo_port.h> 22 23 /* 24 * Common routines to create port entries in the topology tree. 25 */ 26 27 static const topo_pgroup_info_t port_pgroup = { 28 TOPO_PGROUP_PORT, 29 TOPO_STABILITY_PRIVATE, 30 TOPO_STABILITY_PRIVATE, 31 1 32 }; 33 34 int 35 port_range_create(topo_mod_t *mod, tnode_t *pnode, topo_instance_t min, 36 topo_instance_t max) 37 { 38 return (topo_node_range_create(mod, pnode, PORT, min, max)); 39 } 40 41 /* 42 * Create a port node, specifying the type of port it is. This will create the 43 * common port property group and populate it. The caller will need to populate 44 * the port-specific property group as needed. 45 */ 46 static tnode_t * 47 port_create_common(topo_mod_t *mod, tnode_t *pnode, topo_instance_t inst, 48 const char *type) 49 { 50 int err; 51 tnode_t *tn = NULL; 52 nvlist_t *fmri = NULL, *auth = NULL, *presource = NULL; 53 54 if (type == NULL) { 55 topo_mod_dprintf(mod, "port_create_common missing type " 56 "argument\n"); 57 goto error; 58 } 59 60 if ((auth = topo_mod_auth(mod, pnode)) == NULL) { 61 topo_mod_dprintf(mod, "topo_mod_auth() failed: %s\n", 62 topo_mod_errmsg(mod)); 63 goto error; 64 } 65 66 if ((fmri = topo_mod_hcfmri(mod, pnode, FM_HC_SCHEME_VERSION, PORT, 67 inst, NULL, auth, NULL, NULL, NULL)) == NULL) { 68 topo_mod_dprintf(mod, "topo_mod_hcfmri() failed: %s\n", 69 topo_mod_errmsg(mod)); 70 goto error; 71 } 72 73 if ((tn = topo_node_bind(mod, pnode, PORT, inst, fmri)) == NULL) { 74 topo_mod_dprintf(mod, "topo_node_bind() failed: %s\n", 75 topo_mod_errmsg(mod)); 76 goto error; 77 } 78 79 /* 80 * The FRU is always set to the FMRI of the parent device for a port. 81 */ 82 if (topo_node_resource(pnode, &presource, &err) != 0) { 83 topo_mod_dprintf(mod, "topo_node_resource() failed: %s\n", 84 topo_strerror(err)); 85 goto error; 86 } 87 88 if (topo_node_fru_set(tn, presource, 0, &err) != 0) { 89 topo_mod_dprintf(mod, "topo_node_fru_set() failed: %s\n", 90 topo_strerror(err)); 91 goto error; 92 } 93 94 if (topo_pgroup_create(tn, &port_pgroup, &err) != 0) { 95 topo_mod_dprintf(mod, "failed to create property group %s: " 96 "%s\n", TOPO_PGROUP_PORT, topo_strerror(err)); 97 goto error; 98 } 99 100 if (topo_prop_set_string(tn, TOPO_PGROUP_PORT, TOPO_PROP_PORT_TYPE, 101 TOPO_PROP_IMMUTABLE, type, &err) != 0) { 102 topo_mod_dprintf(mod, "failed to set %s property: %s\n", 103 TOPO_PROP_PORT_TYPE, topo_strerror(err)); 104 goto error; 105 } 106 107 nvlist_free(fmri); 108 nvlist_free(auth); 109 nvlist_free(presource); 110 return (tn); 111 error: 112 topo_node_unbind(tn); 113 nvlist_free(fmri); 114 nvlist_free(auth); 115 nvlist_free(presource); 116 return (NULL); 117 } 118 119 int 120 port_create_sff(topo_mod_t *mod, tnode_t *pnode, topo_instance_t inst, 121 tnode_t **nodep) 122 { 123 tnode_t *tn; 124 125 tn = port_create_common(mod, pnode, inst, TOPO_PROP_PORT_TYPE_SFF); 126 if (tn == NULL) 127 return (-1); 128 *nodep = tn; 129 return (0); 130 } 131