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.
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.
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]
22 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
26 * Topology Plugin Modules
28 * Topology plugin modules are shared libraries that are dlopen'd and
29 * used to enumerate resources in the system and export per-node method
32 * They are loaded by our builtin scheme-specific plugins, other modules or
33 * by processing a topo map XML file to enumerate and create nodes for
34 * resources that are present in the system. They may also export a set of
35 * topology node specific methods that can be invoked directly via
36 * topo_method_invoke() or indirectly via the
37 * topo_prop_get* family of functions to access dynamic property data.
41 * Enumerators must provide entry points for initialization and clean-up
42 * (_topo_init() and _topo_fini()). In their _topo_init() function, an
43 * enumerator should register (topo_mod_register()) its enumeration callback
44 * and allocate resources required for a subsequent call to the callback.
45 * Optionally, methods may also be registered with topo_method_register().
47 * In its enumeration callback routine, the module should search for resources
48 * within its realm of responsibility and create any node ranges,
49 * topo_node_range_create() and nodes, topo_node_bind(). The Enumerator
50 * module is handed a node to which it may begin attaching additional
51 * topology nodes. The enumerator may only access those nodes within its
52 * current scope of operation: the node passed into its enumeration op and
53 * any nodes it creates during enumeration. If the enumerator requires walker-
54 * style access to these nodes, it must use
55 * topo_mod_walk_init()/topo_walk_step()/topo_walk_fini().
57 * If additional helper modules need to be loaded to complete the enumeration
58 * the module may do so by calling topo_mod_load(). Enumeration may then
59 * continue with the module handing off enumeration to its helper module
60 * by calling topo_mod_enumerate(). Similarly, a module may call
61 * topo_mod_enummap() to kick-off enumeration according to a given XML
62 * topology map file. A module *may* not cause re-entrance to itself
63 * via either of these interfaces. If re-entry is detected an error
64 * will be returned (ETOPO_ENUM_RECURS).
66 * If the module registers a release callback, it will be called on a node
67 * by node basis during topo_snap_rele(). Any private node data may be
68 * deallocated or methods unregistered at that time. Global module data
69 * should be cleaned up before or at the time that the module _topo_fini
70 * entry point is called.
72 * Module entry points and method invocations are guaranteed to be
73 * single-threaded for a given snapshot handle. Applications may have
74 * more than one topology snapshot open at a time. This means that the
75 * module operations and methods may be called for different module handles
76 * (topo_mod_t) asynchronously. The enumerator should not use static or
77 * global data structures that may become inconsistent in this situation.
78 * Method operations may be re-entrant if the module invokes one of its own
79 * methods directly or via dynamic property access. Caution should be
80 * exercised with method operations to insure that data remains consistent
81 * within the module and that deadlocks can not occur.
93 #include <sys/param.h>
94 #include <sys/utsname.h>
95 #include <sys/smbios.h>
96 #include <sys/fm/protocol.h>
98 #include <topo_alloc.h>
99 #include <topo_error.h>
100 #include <topo_file.h>
101 #include <topo_fmri.h>
102 #include <topo_module.h>
103 #include <topo_method.h>
104 #include <topo_string.h>
105 #include <topo_subr.h>
106 #include <topo_tree.h>
108 #define PLUGIN_PATH "plugins"
109 #define PLUGIN_PATH_LEN MAXNAMELEN + 5
112 topo_mod_load(topo_mod_t
*pmod
, const char *name
,
113 topo_version_t version
)
116 char file
[PLUGIN_PATH_LEN
];
117 topo_mod_t
*mod
= NULL
;
123 * Already loaded, topo_mod_lookup will bump the ref count
125 if ((mod
= topo_mod_lookup(thp
, name
, 1)) != NULL
) {
126 if (mod
->tm_info
->tmi_version
!= version
) {
128 (void) topo_mod_seterrno(pmod
, ETOPO_MOD_VER
);
134 (void) snprintf(file
, PLUGIN_PATH_LEN
, "%s/%s.so",
136 path
= topo_search_path(pmod
, thp
->th_rootdir
, (const char *)file
);
138 (mod
= topo_modhash_load(thp
, name
, path
, &topo_rtld_ops
, version
))
139 == NULL
) { /* returned with mod held */
140 topo_mod_strfree(pmod
, path
);
141 (void) topo_mod_seterrno(pmod
, topo_hdl_errno(thp
) ?
142 topo_hdl_errno(thp
) : ETOPO_MOD_NOENT
);
146 topo_mod_strfree(pmod
, path
);
152 topo_mod_unload(topo_mod_t
*mod
)
158 set_register_error(topo_mod_t
*mod
, int err
)
160 if (mod
->tm_info
!= NULL
)
161 topo_mod_unregister(mod
);
163 topo_dprintf(mod
->tm_hdl
, TOPO_DBG_ERR
,
164 "module registration failed for %s: %s\n",
165 mod
->tm_name
, topo_strerror(err
));
167 return (topo_mod_seterrno(mod
, err
));
171 topo_mod_register(topo_mod_t
*mod
, const topo_modinfo_t
*mip
,
172 topo_version_t version
)
175 assert(!(mod
->tm_flags
& TOPO_MOD_FINI
||
176 mod
->tm_flags
& TOPO_MOD_REG
));
178 if (version
!= TOPO_VERSION
)
179 return (set_register_error(mod
, EMOD_VER_ABI
));
181 if ((mod
->tm_info
= topo_mod_zalloc(mod
, sizeof (topo_imodinfo_t
)))
183 return (set_register_error(mod
, EMOD_NOMEM
));
184 if ((mod
->tm_info
->tmi_ops
= topo_mod_alloc(mod
,
185 sizeof (topo_modops_t
))) == NULL
)
186 return (set_register_error(mod
, EMOD_NOMEM
));
188 mod
->tm_info
->tmi_desc
= topo_mod_strdup(mod
, mip
->tmi_desc
);
189 if (mod
->tm_info
->tmi_desc
== NULL
)
190 return (set_register_error(mod
, EMOD_NOMEM
));
192 mod
->tm_info
->tmi_scheme
= topo_mod_strdup(mod
, mip
->tmi_scheme
);
193 if (mod
->tm_info
->tmi_scheme
== NULL
)
194 return (set_register_error(mod
, EMOD_NOMEM
));
197 mod
->tm_info
->tmi_version
= (topo_version_t
)mip
->tmi_version
;
198 mod
->tm_info
->tmi_ops
->tmo_enum
= mip
->tmi_ops
->tmo_enum
;
199 mod
->tm_info
->tmi_ops
->tmo_release
= mip
->tmi_ops
->tmo_release
;
201 mod
->tm_flags
|= TOPO_MOD_REG
;
203 topo_dprintf(mod
->tm_hdl
, TOPO_DBG_MODSVC
,
204 "registration succeeded for %s\n", mod
->tm_name
);
210 topo_mod_unregister(topo_mod_t
*mod
)
212 if (mod
->tm_info
== NULL
)
215 assert(!(mod
->tm_flags
& TOPO_MOD_FINI
));
217 mod
->tm_flags
&= ~TOPO_MOD_REG
;
219 if (mod
->tm_info
== NULL
)
222 if (mod
->tm_info
->tmi_ops
!= NULL
)
223 topo_mod_free(mod
, mod
->tm_info
->tmi_ops
,
224 sizeof (topo_modops_t
));
225 if (mod
->tm_info
->tmi_desc
!= NULL
)
226 topo_mod_strfree(mod
, mod
->tm_info
->tmi_desc
);
227 if (mod
->tm_info
->tmi_scheme
!= NULL
)
228 topo_mod_strfree(mod
, mod
->tm_info
->tmi_scheme
);
230 topo_mod_free(mod
, mod
->tm_info
, sizeof (topo_imodinfo_t
));
236 topo_mod_enumerate(topo_mod_t
*mod
, tnode_t
*node
, const char *enum_name
,
237 const char *name
, topo_instance_t min
, topo_instance_t max
, void *data
)
240 topo_mod_t
*enum_mod
;
242 assert(mod
->tm_flags
& TOPO_MOD_REG
);
244 if ((enum_mod
= topo_mod_lookup(mod
->tm_hdl
, enum_name
, 0)) == NULL
)
245 return (topo_mod_seterrno(mod
, EMOD_MOD_NOENT
));
247 topo_node_hold(node
);
249 topo_dprintf(mod
->tm_hdl
, TOPO_DBG_MODSVC
, "module %s enumerating "
250 "node %s=%d\n", (char *)mod
->tm_name
, (char *)node
->tn_name
,
253 topo_mod_enter(enum_mod
);
254 err
= enum_mod
->tm_info
->tmi_ops
->tmo_enum(enum_mod
, node
, name
, min
,
255 max
, enum_mod
->tm_priv
, data
);
256 topo_mod_exit(enum_mod
);
259 (void) topo_mod_seterrno(mod
, EMOD_UKNOWN_ENUM
);
261 topo_dprintf(mod
->tm_hdl
, TOPO_DBG_ERR
,
262 "module %s failed enumeration for "
263 " node %s=%d\n", (char *)mod
->tm_name
,
264 (char *)node
->tn_name
, node
->tn_instance
);
266 topo_node_rele(node
);
270 topo_node_rele(node
);
276 topo_mod_enummap(topo_mod_t
*mod
, tnode_t
*node
, const char *name
,
279 return (topo_file_load(mod
, node
, (char *)name
, (char *)scheme
, 0));
283 set_fmri_err(topo_mod_t
*mod
, int err
)
285 (void) topo_mod_seterrno(mod
, err
);
290 topo_mod_hcfmri(topo_mod_t
*mod
, tnode_t
*pnode
, int version
, const char *name
,
291 topo_instance_t inst
, nvlist_t
*hc_specific
, nvlist_t
*auth
,
292 const char *part
, const char *rev
, const char *serial
)
295 nvlist_t
*pfmri
= NULL
, *fmri
= NULL
, *args
= NULL
;
296 nvlist_t
*nfp
= NULL
;
297 char *lpart
, *lrev
, *lserial
;
299 if (version
!= FM_HC_SCHEME_VERSION
)
300 return (set_fmri_err(mod
, EMOD_FMRI_VERSION
));
303 * Do we have any args to pass?
305 if (pnode
!= NULL
|| auth
!= NULL
|| part
!= NULL
|| rev
!= NULL
||
306 serial
!= NULL
|| hc_specific
!= NULL
) {
307 if (topo_mod_nvalloc(mod
, &args
, NV_UNIQUE_NAME
) != 0)
308 return (set_fmri_err(mod
, EMOD_FMRI_NVL
));
312 if (topo_node_resource(pnode
, &pfmri
, &err
) < 0) {
314 return (set_fmri_err(mod
, EMOD_NVL_INVAL
));
317 if (nvlist_add_nvlist(args
, TOPO_METH_FMRI_ARG_PARENT
,
321 return (set_fmri_err(mod
, EMOD_FMRI_NVL
));
327 * Add optional payload
330 (void) nvlist_add_nvlist(args
, TOPO_METH_FMRI_ARG_AUTH
, auth
);
332 lpart
= topo_cleanup_auth_str(mod
->tm_hdl
, part
);
334 (void) nvlist_add_string(args
, TOPO_METH_FMRI_ARG_PART
,
336 topo_hdl_free(mod
->tm_hdl
, lpart
, strlen(lpart
) + 1);
338 (void) nvlist_add_string(args
, TOPO_METH_FMRI_ARG_PART
,
343 lrev
= topo_cleanup_auth_str(mod
->tm_hdl
, rev
);
345 (void) nvlist_add_string(args
, TOPO_METH_FMRI_ARG_REV
,
347 topo_hdl_free(mod
->tm_hdl
, lrev
, strlen(lrev
) + 1);
349 (void) nvlist_add_string(args
, TOPO_METH_FMRI_ARG_REV
,
353 if (serial
!= NULL
) {
354 lserial
= topo_cleanup_auth_str(mod
->tm_hdl
, serial
);
355 if (lserial
!= NULL
) {
356 (void) nvlist_add_string(args
, TOPO_METH_FMRI_ARG_SER
,
358 topo_hdl_free(mod
->tm_hdl
, lserial
,
359 strlen(lserial
) + 1);
361 (void) nvlist_add_string(args
, TOPO_METH_FMRI_ARG_SER
,
365 if (hc_specific
!= NULL
)
366 (void) nvlist_add_nvlist(args
, TOPO_METH_FMRI_ARG_HCS
,
369 if ((fmri
= topo_fmri_create(mod
->tm_hdl
, FM_FMRI_SCHEME_HC
, name
, inst
,
370 args
, &err
)) == NULL
) {
372 return (set_fmri_err(mod
, err
));
377 (void) topo_mod_nvdup(mod
, fmri
, &nfp
);
384 topo_mod_devfmri(topo_mod_t
*mod
, int version
, const char *dev_path
,
388 nvlist_t
*fmri
, *args
;
389 nvlist_t
*nfp
= NULL
;
391 if (version
!= FM_DEV_SCHEME_VERSION
)
392 return (set_fmri_err(mod
, EMOD_FMRI_VERSION
));
394 if (topo_mod_nvalloc(mod
, &args
, NV_UNIQUE_NAME
) != 0)
395 return (set_fmri_err(mod
, EMOD_FMRI_NVL
));
397 if (nvlist_add_string(args
, FM_FMRI_DEV_PATH
, dev_path
) != 0) {
399 return (set_fmri_err(mod
, EMOD_FMRI_NVL
));
402 (void) nvlist_add_string(args
, FM_FMRI_DEV_ID
, devid
);
404 if ((fmri
= topo_fmri_create(mod
->tm_hdl
, FM_FMRI_SCHEME_DEV
,
405 FM_FMRI_SCHEME_DEV
, 0, args
, &err
)) == NULL
) {
407 return (set_fmri_err(mod
, err
));
412 (void) topo_mod_nvdup(mod
, fmri
, &nfp
);
419 topo_mod_cpufmri(topo_mod_t
*mod
, int version
, uint32_t cpu_id
, uint8_t cpumask
,
423 nvlist_t
*fmri
= NULL
, *args
= NULL
;
424 nvlist_t
*nfp
= NULL
;
426 if (version
!= FM_CPU_SCHEME_VERSION
)
427 return (set_fmri_err(mod
, EMOD_FMRI_VERSION
));
429 if (topo_mod_nvalloc(mod
, &args
, NV_UNIQUE_NAME
) != 0)
430 return (set_fmri_err(mod
, EMOD_FMRI_NVL
));
432 if (nvlist_add_uint32(args
, FM_FMRI_CPU_ID
, cpu_id
) != 0) {
434 return (set_fmri_err(mod
, EMOD_FMRI_NVL
));
438 * Add optional payload
440 (void) nvlist_add_uint8(args
, FM_FMRI_CPU_MASK
, cpumask
);
441 (void) nvlist_add_string(args
, FM_FMRI_CPU_SERIAL_ID
, serial
);
443 if ((fmri
= topo_fmri_create(mod
->tm_hdl
, FM_FMRI_SCHEME_CPU
,
444 FM_FMRI_SCHEME_CPU
, 0, args
, &err
)) == NULL
) {
446 return (set_fmri_err(mod
, err
));
451 (void) topo_mod_nvdup(mod
, fmri
, &nfp
);
458 topo_mod_memfmri(topo_mod_t
*mod
, int version
, uint64_t pa
, uint64_t offset
,
459 const char *unum
, int flags
)
462 nvlist_t
*args
= NULL
, *fmri
= NULL
;
463 nvlist_t
*nfp
= NULL
;
465 if (version
!= FM_MEM_SCHEME_VERSION
)
466 return (set_fmri_err(mod
, EMOD_FMRI_VERSION
));
468 if (topo_mod_nvalloc(mod
, &args
, NV_UNIQUE_NAME
) != 0)
469 return (set_fmri_err(mod
, EMOD_FMRI_NVL
));
471 err
= nvlist_add_string(args
, FM_FMRI_MEM_UNUM
, unum
);
473 if (flags
& TOPO_MEMFMRI_PA
)
474 err
|= nvlist_add_uint64(args
, FM_FMRI_MEM_PHYSADDR
, pa
);
475 if (flags
& TOPO_MEMFMRI_OFFSET
)
476 err
|= nvlist_add_uint64(args
, FM_FMRI_MEM_OFFSET
, offset
);
480 return (set_fmri_err(mod
, EMOD_FMRI_NVL
));
483 if ((fmri
= topo_fmri_create(mod
->tm_hdl
, FM_FMRI_SCHEME_MEM
,
484 FM_FMRI_SCHEME_MEM
, 0, args
, &err
)) == NULL
) {
486 return (set_fmri_err(mod
, err
));
491 (void) topo_mod_nvdup(mod
, fmri
, &nfp
);
499 topo_mod_pkgfmri(topo_mod_t
*mod
, int version
, const char *path
)
502 nvlist_t
*fmri
= NULL
, *args
= NULL
;
503 nvlist_t
*nfp
= NULL
;
505 if (version
!= FM_PKG_SCHEME_VERSION
)
506 return (set_fmri_err(mod
, EMOD_FMRI_VERSION
));
508 if (topo_mod_nvalloc(mod
, &args
, NV_UNIQUE_NAME
) != 0)
509 return (set_fmri_err(mod
, EMOD_FMRI_NVL
));
511 if (nvlist_add_string(args
, "path", path
) != 0) {
513 return (set_fmri_err(mod
, EMOD_FMRI_NVL
));
516 if ((fmri
= topo_fmri_create(mod
->tm_hdl
, FM_FMRI_SCHEME_PKG
,
517 FM_FMRI_SCHEME_PKG
, 0, args
, &err
)) == NULL
) {
519 return (set_fmri_err(mod
, err
));
524 (void) topo_mod_nvdup(mod
, fmri
, &nfp
);
531 topo_mod_modfmri(topo_mod_t
*mod
, int version
, const char *driver
)
534 nvlist_t
*fmri
= NULL
, *args
= NULL
;
535 nvlist_t
*nfp
= NULL
;
537 if (version
!= FM_MOD_SCHEME_VERSION
)
538 return (set_fmri_err(mod
, EMOD_FMRI_VERSION
));
540 if (topo_mod_nvalloc(mod
, &args
, NV_UNIQUE_NAME
) != 0)
541 return (set_fmri_err(mod
, EMOD_FMRI_NVL
));
543 if (nvlist_add_string(args
, "DRIVER", driver
) != 0) {
545 return (set_fmri_err(mod
, EMOD_FMRI_NVL
));
548 if ((fmri
= topo_fmri_create(mod
->tm_hdl
, FM_FMRI_SCHEME_MOD
,
549 FM_FMRI_SCHEME_MOD
, 0, args
, &err
)) == NULL
) {
551 return (set_fmri_err(mod
, err
));
556 (void) topo_mod_nvdup(mod
, fmri
, &nfp
);
562 #define _SWFMRI_ADD_STRING(nvl, name, val) \
563 ((val) ? (nvlist_add_string(nvl, name, val) != 0) : 0)
566 topo_mod_swfmri(topo_mod_t
*mod
, int version
,
567 char *obj_path
, char *obj_root
, nvlist_t
*obj_pkg
,
568 char *site_token
, char *site_module
, char *site_file
, char *site_func
,
569 int64_t site_line
, char *ctxt_origin
, char *ctxt_execname
,
570 int64_t ctxt_pid
, char *ctxt_zone
, int64_t ctxt_ctid
,
571 char **ctxt_stack
, uint_t ctxt_stackdepth
)
573 nvlist_t
*fmri
, *args
;
574 nvlist_t
*nfp
= NULL
;
577 if (version
!= FM_SW_SCHEME_VERSION
)
578 return (set_fmri_err(mod
, EMOD_FMRI_VERSION
));
580 if (topo_mod_nvalloc(mod
, &args
, NV_UNIQUE_NAME
) != 0)
581 return (set_fmri_err(mod
, EMOD_FMRI_NVL
));
584 err
|= _SWFMRI_ADD_STRING(args
, "obj_path", obj_path
);
585 err
|= _SWFMRI_ADD_STRING(args
, "obj_root", obj_root
);
587 err
|= nvlist_add_nvlist(args
, "obj_pkg", obj_pkg
);
589 err
|= _SWFMRI_ADD_STRING(args
, "site_token", site_token
);
590 err
|= _SWFMRI_ADD_STRING(args
, "site_module", site_module
);
591 err
|= _SWFMRI_ADD_STRING(args
, "site_file", site_file
);
592 err
|= _SWFMRI_ADD_STRING(args
, "site_func", site_func
);
594 err
|= nvlist_add_int64(args
, "site_line", site_line
);
596 err
|= _SWFMRI_ADD_STRING(args
, "ctxt_origin", ctxt_origin
);
597 err
|= _SWFMRI_ADD_STRING(args
, "ctxt_execname", ctxt_execname
);
599 err
|= nvlist_add_int64(args
, "ctxt_pid", ctxt_pid
);
600 err
|= _SWFMRI_ADD_STRING(args
, "ctxt_zone", ctxt_zone
);
602 err
|= nvlist_add_int64(args
, "ctxt_ctid", ctxt_ctid
);
603 if (ctxt_stack
!= NULL
&& ctxt_stackdepth
!= 0)
604 err
|= nvlist_add_string_array(args
, "stack", ctxt_stack
,
609 return (set_fmri_err(mod
, EMOD_FMRI_NVL
));
612 if ((fmri
= topo_fmri_create(mod
->tm_hdl
, FM_FMRI_SCHEME_SW
,
613 FM_FMRI_SCHEME_SW
, 0, args
, &err
)) == NULL
) {
615 return (set_fmri_err(mod
, err
));
620 (void) topo_mod_nvdup(mod
, fmri
, &nfp
);
627 topo_mod_str2nvl(topo_mod_t
*mod
, const char *fmristr
, nvlist_t
**fmri
)
632 if (topo_fmri_str2nvl(mod
->tm_hdl
, fmristr
, &np
, &err
) < 0)
633 return (topo_mod_seterrno(mod
, err
));
635 if (topo_mod_nvdup(mod
, np
, fmri
) < 0) {
637 return (topo_mod_seterrno(mod
, EMOD_FMRI_NVL
));
646 topo_mod_nvl2str(topo_mod_t
*mod
, nvlist_t
*fmri
, char **fmristr
)
651 if (topo_fmri_nvl2str(mod
->tm_hdl
, fmri
, &sp
, &err
) < 0)
652 return (topo_mod_seterrno(mod
, err
));
654 if ((*fmristr
= topo_mod_strdup(mod
, sp
)) == NULL
) {
655 topo_hdl_strfree(mod
->tm_hdl
, sp
);
656 return (topo_mod_seterrno(mod
, EMOD_NOMEM
));
659 topo_hdl_strfree(mod
->tm_hdl
, sp
);
665 topo_mod_getspecific(topo_mod_t
*mod
)
667 return (mod
->tm_priv
);
671 topo_mod_setspecific(topo_mod_t
*mod
, void *data
)
677 topo_mod_setdebug(topo_mod_t
*mod
)
683 topo_mod_ipmi_hold(topo_mod_t
*mod
)
685 topo_hdl_t
*thp
= mod
->tm_hdl
;
689 (void) pthread_mutex_lock(&thp
->th_ipmi_lock
);
690 if (thp
->th_ipmi
== NULL
) {
691 if ((thp
->th_ipmi
= ipmi_open(&err
, &errmsg
, IPMI_TRANSPORT_BMC
,
693 topo_dprintf(mod
->tm_hdl
, TOPO_DBG_ERR
,
694 "ipmi_open() failed: %s (ipmi errno=%d)", errmsg
,
696 (void) pthread_mutex_unlock(&thp
->th_ipmi_lock
);
701 return (thp
->th_ipmi
);
705 topo_mod_ipmi_rele(topo_mod_t
*mod
)
707 topo_hdl_t
*thp
= mod
->tm_hdl
;
709 (void) pthread_mutex_unlock(&thp
->th_ipmi_lock
);
713 topo_mod_devinfo(topo_mod_t
*mod
)
715 return (topo_hdl_devinfo(mod
->tm_hdl
));
719 topo_mod_smbios(topo_mod_t
*mod
)
721 topo_hdl_t
*thp
= mod
->tm_hdl
;
723 if (thp
->th_smbios
== NULL
)
724 thp
->th_smbios
= smbios_open(NULL
, SMB_VERSION
, 0, NULL
);
726 return (thp
->th_smbios
);
730 topo_mod_prominfo(topo_mod_t
*mod
)
732 return (topo_hdl_prominfo(mod
->tm_hdl
));
736 topo_mod_clrdebug(topo_mod_t
*mod
)
743 topo_mod_dprintf(topo_mod_t
*mod
, const char *format
, ...)
747 if (mod
->tm_debug
== 0)
750 va_start(alist
, format
);
751 topo_vdprintf(mod
->tm_hdl
, TOPO_DBG_MOD
, (const char *)mod
->tm_name
,
757 topo_mod_product(topo_mod_t
*mod
)
759 return (topo_mod_strdup(mod
, mod
->tm_hdl
->th_product
));
763 topo_mod_server(topo_mod_t
*mod
)
765 static struct utsname uts
;
768 return (topo_mod_strdup(mod
, uts
.nodename
));
772 topo_mod_psn(topo_mod_t
*mod
)
777 if ((shp
= topo_mod_smbios(mod
)) == NULL
||
778 (psn
= smbios_psn(shp
)) == NULL
)
781 return (topo_cleanup_auth_str(mod
->tm_hdl
, psn
));
785 topo_mod_csn(topo_mod_t
*mod
)
787 char csn
[MAXNAMELEN
];
789 di_prom_handle_t promh
= DI_PROM_HANDLE_NIL
;
790 di_node_t rooth
= DI_NODE_NIL
;
793 if ((shp
= topo_mod_smbios(mod
)) != NULL
) {
794 bufp
= smbios_csn(shp
);
796 (void) strlcpy(csn
, bufp
, MAXNAMELEN
);
799 } else if ((rooth
= topo_mod_devinfo(mod
)) != DI_NODE_NIL
&&
800 (promh
= topo_mod_prominfo(mod
)) != DI_PROM_HANDLE_NIL
) {
801 if (di_prom_prop_lookup_bytes(promh
, rooth
, "chassis-sn",
802 (unsigned char **)&bufp
) != -1) {
803 (void) strlcpy(csn
, bufp
, MAXNAMELEN
);
811 return (topo_cleanup_auth_str(mod
->tm_hdl
, csn
));
815 topo_mod_auth(topo_mod_t
*mod
, tnode_t
*pnode
)
824 if ((err
= topo_mod_nvalloc(mod
, &auth
, NV_UNIQUE_NAME
)) != 0) {
825 (void) topo_mod_seterrno(mod
, EMOD_FMRI_NVL
);
829 (void) topo_prop_get_string(pnode
, FM_FMRI_AUTHORITY
,
830 FM_FMRI_AUTH_PRODUCT
, &prod
, &err
);
831 (void) topo_prop_get_string(pnode
, FM_FMRI_AUTHORITY
,
832 FM_FMRI_AUTH_PRODUCT_SN
, &psn
, &err
);
833 (void) topo_prop_get_string(pnode
, FM_FMRI_AUTHORITY
,
834 FM_FMRI_AUTH_CHASSIS
, &csn
, &err
);
835 (void) topo_prop_get_string(pnode
, FM_FMRI_AUTHORITY
,
836 FM_FMRI_AUTH_SERVER
, &server
, &err
);
839 * Let's do this the hard way
842 prod
= topo_mod_product(mod
);
844 csn
= topo_mod_csn(mod
);
846 psn
= topo_mod_psn(mod
);
847 if (server
== NULL
) {
848 server
= topo_mod_server(mod
);
852 * No luck, return NULL
854 if (!prod
&& !server
&& !csn
&& !psn
) {
861 err
|= nvlist_add_string(auth
, FM_FMRI_AUTH_PRODUCT
, prod
);
862 topo_mod_strfree(mod
, prod
);
865 err
|= nvlist_add_string(auth
, FM_FMRI_AUTH_PRODUCT_SN
, psn
);
866 topo_mod_strfree(mod
, psn
);
868 if (server
!= NULL
) {
869 err
|= nvlist_add_string(auth
, FM_FMRI_AUTH_SERVER
, server
);
870 topo_mod_strfree(mod
, server
);
873 err
|= nvlist_add_string(auth
, FM_FMRI_AUTH_CHASSIS
, csn
);
874 topo_mod_strfree(mod
, csn
);
879 (void) topo_mod_seterrno(mod
, EMOD_NVL_INVAL
);
887 topo_mod_walk_init(topo_mod_t
*mod
, tnode_t
*node
, topo_mod_walk_cb_t cb_f
,
888 void *pdata
, int *errp
)
891 topo_hdl_t
*thp
= mod
->tm_hdl
;
893 if ((wp
= topo_node_walk_init(thp
, mod
, node
, (int (*)())cb_f
, pdata
,