110942STom.Pothier@Sun.COM /*
210942STom.Pothier@Sun.COM * CDDL HEADER START
310942STom.Pothier@Sun.COM *
410942STom.Pothier@Sun.COM * The contents of this file are subject to the terms of the
510942STom.Pothier@Sun.COM * Common Development and Distribution License (the "License").
610942STom.Pothier@Sun.COM * You may not use this file except in compliance with the License.
710942STom.Pothier@Sun.COM *
810942STom.Pothier@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910942STom.Pothier@Sun.COM * or http://www.opensolaris.org/os/licensing.
1010942STom.Pothier@Sun.COM * See the License for the specific language governing permissions
1110942STom.Pothier@Sun.COM * and limitations under the License.
1210942STom.Pothier@Sun.COM *
1310942STom.Pothier@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
1410942STom.Pothier@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510942STom.Pothier@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
1610942STom.Pothier@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
1710942STom.Pothier@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
1810942STom.Pothier@Sun.COM *
1910942STom.Pothier@Sun.COM * CDDL HEADER END
2010942STom.Pothier@Sun.COM */
2110942STom.Pothier@Sun.COM
2210942STom.Pothier@Sun.COM /*
23*12832STrang.Do@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2410942STom.Pothier@Sun.COM */
2510942STom.Pothier@Sun.COM
2610942STom.Pothier@Sun.COM /*
2710942STom.Pothier@Sun.COM * Subroutines used by the i86pc Generic Topology Enumerator
2810942STom.Pothier@Sun.COM */
2910942STom.Pothier@Sun.COM
3010942STom.Pothier@Sun.COM #include <sys/types.h>
3110942STom.Pothier@Sun.COM #include <strings.h>
3210942STom.Pothier@Sun.COM #include <deflt.h>
3310942STom.Pothier@Sun.COM #include <fcntl.h>
3410942STom.Pothier@Sun.COM #include <unistd.h>
3510942STom.Pothier@Sun.COM #include <fm/topo_mod.h>
3610942STom.Pothier@Sun.COM #include <fm/topo_hc.h>
3710942STom.Pothier@Sun.COM #include <sys/devfm.h>
3811859STom.Pothier@Sun.COM #include <sys/pci.h>
3910942STom.Pothier@Sun.COM #include <sys/systeminfo.h>
4010942STom.Pothier@Sun.COM #include <sys/fm/protocol.h>
4110942STom.Pothier@Sun.COM #include <sys/utsname.h>
4210942STom.Pothier@Sun.COM #include <sys/smbios.h>
4310942STom.Pothier@Sun.COM #include <sys/smbios_impl.h>
4410942STom.Pothier@Sun.COM #include <x86pi_impl.h>
4510942STom.Pothier@Sun.COM
4610942STom.Pothier@Sun.COM
4710942STom.Pothier@Sun.COM static const topo_pgroup_info_t sys_pgroup = {
4810942STom.Pothier@Sun.COM TOPO_PGROUP_SYSTEM,
4910942STom.Pothier@Sun.COM TOPO_STABILITY_PRIVATE,
5010942STom.Pothier@Sun.COM TOPO_STABILITY_PRIVATE,
5110942STom.Pothier@Sun.COM 1
5210942STom.Pothier@Sun.COM };
5310942STom.Pothier@Sun.COM
5410942STom.Pothier@Sun.COM static const topo_pgroup_info_t auth_pgroup = {
5510942STom.Pothier@Sun.COM FM_FMRI_AUTHORITY,
5610942STom.Pothier@Sun.COM TOPO_STABILITY_PRIVATE,
5710942STom.Pothier@Sun.COM TOPO_STABILITY_PRIVATE,
5810942STom.Pothier@Sun.COM 1
5910942STom.Pothier@Sun.COM };
6010942STom.Pothier@Sun.COM
6110942STom.Pothier@Sun.COM
6210942STom.Pothier@Sun.COM /*
6310942STom.Pothier@Sun.COM * Free hcfmri strings.
6410942STom.Pothier@Sun.COM */
6510942STom.Pothier@Sun.COM void
x86pi_hcfmri_info_fini(topo_mod_t * mod,x86pi_hcfmri_t * hc)6610942STom.Pothier@Sun.COM x86pi_hcfmri_info_fini(topo_mod_t *mod, x86pi_hcfmri_t *hc)
6710942STom.Pothier@Sun.COM {
6810942STom.Pothier@Sun.COM if (hc->hc_name != NULL)
6910942STom.Pothier@Sun.COM topo_mod_strfree(mod, (char *)hc->hc_name);
7010942STom.Pothier@Sun.COM if (hc->manufacturer != NULL)
7110942STom.Pothier@Sun.COM topo_mod_strfree(mod, (char *)hc->manufacturer);
7210942STom.Pothier@Sun.COM if (hc->product != NULL)
7310942STom.Pothier@Sun.COM topo_mod_strfree(mod, (char *)hc->product);
7410942STom.Pothier@Sun.COM if (hc->version != NULL)
7510942STom.Pothier@Sun.COM topo_mod_strfree(mod, (char *)hc->version);
7610942STom.Pothier@Sun.COM if (hc->serial_number != NULL)
7710942STom.Pothier@Sun.COM topo_mod_strfree(mod, (char *)hc->serial_number);
7810942STom.Pothier@Sun.COM if (hc->asset_tag != NULL)
7910942STom.Pothier@Sun.COM topo_mod_strfree(mod, (char *)hc->asset_tag);
8010942STom.Pothier@Sun.COM if (hc->location != NULL)
8110942STom.Pothier@Sun.COM topo_mod_strfree(mod, (char *)hc->location);
8210942STom.Pothier@Sun.COM if (hc->part_number != NULL)
8310942STom.Pothier@Sun.COM topo_mod_strfree(mod, (char *)hc->part_number);
8410942STom.Pothier@Sun.COM }
8510942STom.Pothier@Sun.COM
8610942STom.Pothier@Sun.COM
8710942STom.Pothier@Sun.COM /*
8810942STom.Pothier@Sun.COM * Get the server hostname (the ID as far as the topo authority is
8910942STom.Pothier@Sun.COM * concerned) from sysinfo and return a copy to the caller.
9010942STom.Pothier@Sun.COM *
9110942STom.Pothier@Sun.COM * The string must be freed with topo_mod_strfree()
9210942STom.Pothier@Sun.COM */
9310942STom.Pothier@Sun.COM char *
x86pi_get_serverid(topo_mod_t * mod)9410942STom.Pothier@Sun.COM x86pi_get_serverid(topo_mod_t *mod)
9510942STom.Pothier@Sun.COM {
9610942STom.Pothier@Sun.COM int result;
9710942STom.Pothier@Sun.COM char hostname[MAXNAMELEN];
9810942STom.Pothier@Sun.COM
9910942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "x86pi_get_serverid\n");
10010942STom.Pothier@Sun.COM
10110942STom.Pothier@Sun.COM result = sysinfo(SI_HOSTNAME, hostname, sizeof (hostname));
10210942STom.Pothier@Sun.COM /* Everything is freed up and it's time to return the platform-id */
10310942STom.Pothier@Sun.COM if (result == -1) {
10410942STom.Pothier@Sun.COM return (NULL);
10510942STom.Pothier@Sun.COM }
10610942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "x86pi_get_serverid: hostname = %s\n", hostname);
10710942STom.Pothier@Sun.COM
10810942STom.Pothier@Sun.COM return (topo_mod_strdup(mod, hostname));
10910942STom.Pothier@Sun.COM }
11010942STom.Pothier@Sun.COM
11110942STom.Pothier@Sun.COM
11210942STom.Pothier@Sun.COM /*
11310942STom.Pothier@Sun.COM * Get copy of SMBIOS.
11410942STom.Pothier@Sun.COM */
11510942STom.Pothier@Sun.COM smbios_hdl_t *
x86pi_smb_open(topo_mod_t * mod)11610942STom.Pothier@Sun.COM x86pi_smb_open(topo_mod_t *mod)
11710942STom.Pothier@Sun.COM {
11810942STom.Pothier@Sun.COM smbios_hdl_t *smb_hdl;
11910942STom.Pothier@Sun.COM char *f = "x86pi_smb_open";
12010942STom.Pothier@Sun.COM
12110942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s\n", f);
12210942STom.Pothier@Sun.COM
12310942STom.Pothier@Sun.COM smb_hdl = topo_mod_smbios(mod);
12410942STom.Pothier@Sun.COM if (smb_hdl == NULL) {
12510942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: failed to load SMBIOS\n", f);
12610942STom.Pothier@Sun.COM return (NULL);
12710942STom.Pothier@Sun.COM }
12810942STom.Pothier@Sun.COM
12910942STom.Pothier@Sun.COM return (smb_hdl);
13010942STom.Pothier@Sun.COM }
13110942STom.Pothier@Sun.COM
13210942STom.Pothier@Sun.COM
13310942STom.Pothier@Sun.COM /*
13410942STom.Pothier@Sun.COM * Go through the smbios structures looking for a type. Fill in
13510942STom.Pothier@Sun.COM * the structure count as well as the id(s) of the struct types.
13610942STom.Pothier@Sun.COM */
13710942STom.Pothier@Sun.COM void
x86pi_smb_strcnt(topo_mod_t * mod,smbs_cnt_t * stype)138*12832STrang.Do@Sun.COM x86pi_smb_strcnt(topo_mod_t *mod, smbs_cnt_t *stype)
13910942STom.Pothier@Sun.COM {
140*12832STrang.Do@Sun.COM const smb_struct_t *sp;
141*12832STrang.Do@Sun.COM int nstructs;
14210942STom.Pothier@Sun.COM int i, cnt;
143*12832STrang.Do@Sun.COM smbios_hdl_t *shp;
144*12832STrang.Do@Sun.COM
145*12832STrang.Do@Sun.COM shp = topo_mod_smbios(mod);
146*12832STrang.Do@Sun.COM if (shp == NULL) {
147*12832STrang.Do@Sun.COM stype->count = 0;
148*12832STrang.Do@Sun.COM return;
149*12832STrang.Do@Sun.COM }
150*12832STrang.Do@Sun.COM
151*12832STrang.Do@Sun.COM nstructs = shp->sh_nstructs;
152*12832STrang.Do@Sun.COM sp = shp->sh_structs;
15310942STom.Pothier@Sun.COM
15410942STom.Pothier@Sun.COM for (i = 0, cnt = 0; i < nstructs; i++, sp++) {
15510942STom.Pothier@Sun.COM if (sp->smbst_hdr->smbh_type == stype->type) {
15610942STom.Pothier@Sun.COM stype->ids[cnt].node = NULL;
15710942STom.Pothier@Sun.COM stype->ids[cnt].id = sp->smbst_hdr->smbh_hdl;
15810942STom.Pothier@Sun.COM cnt++;
15910942STom.Pothier@Sun.COM }
16010942STom.Pothier@Sun.COM }
16110942STom.Pothier@Sun.COM
16210942STom.Pothier@Sun.COM stype->count = cnt;
16310942STom.Pothier@Sun.COM }
16410942STom.Pothier@Sun.COM
16510942STom.Pothier@Sun.COM
16610942STom.Pothier@Sun.COM /*
16710942STom.Pothier@Sun.COM * Calculate the authority information for a node. Inherit the data if
16810942STom.Pothier@Sun.COM * possible, but always create an appropriate property group.
16910942STom.Pothier@Sun.COM */
17010942STom.Pothier@Sun.COM int
x86pi_set_auth(topo_mod_t * mod,x86pi_hcfmri_t * hcfmri,tnode_t * t_parent,tnode_t * t_node)17110942STom.Pothier@Sun.COM x86pi_set_auth(topo_mod_t *mod, x86pi_hcfmri_t *hcfmri, tnode_t *t_parent,
17210942STom.Pothier@Sun.COM tnode_t *t_node)
17310942STom.Pothier@Sun.COM {
17410942STom.Pothier@Sun.COM int result;
17510942STom.Pothier@Sun.COM int err;
17610942STom.Pothier@Sun.COM int is_chassis = 0;
17710942STom.Pothier@Sun.COM int chassis_instance = 0;
17810942STom.Pothier@Sun.COM nvlist_t *auth;
17910942STom.Pothier@Sun.COM char *val = NULL;
18010942STom.Pothier@Sun.COM char *prod = NULL;
18110942STom.Pothier@Sun.COM char *psn = NULL;
18210942STom.Pothier@Sun.COM char *csn = NULL;
18310942STom.Pothier@Sun.COM char *server = NULL;
18410942STom.Pothier@Sun.COM char *f = "x86pi_set_auth";
18510942STom.Pothier@Sun.COM
18610942STom.Pothier@Sun.COM if (mod == NULL || t_parent == NULL || t_node == NULL) {
18710942STom.Pothier@Sun.COM return (-1);
18810942STom.Pothier@Sun.COM }
18910942STom.Pothier@Sun.COM
19010942STom.Pothier@Sun.COM result = topo_pgroup_create(t_node, &auth_pgroup, &err);
19110942STom.Pothier@Sun.COM if (result != 0 && err != ETOPO_PROP_DEFD) {
19210942STom.Pothier@Sun.COM /*
19310942STom.Pothier@Sun.COM * We failed to create the property group and it was not
19410942STom.Pothier@Sun.COM * already defined. Set the err code and return failure.
19510942STom.Pothier@Sun.COM */
19610983STom.Pothier@Sun.COM (void) topo_mod_seterrno(mod, err);
19710942STom.Pothier@Sun.COM return (-1);
19810942STom.Pothier@Sun.COM }
19910942STom.Pothier@Sun.COM
20010942STom.Pothier@Sun.COM /* Get the authority information already available from the parent */
20110942STom.Pothier@Sun.COM auth = topo_mod_auth(mod, t_parent);
20210942STom.Pothier@Sun.COM
20310942STom.Pothier@Sun.COM /* Determnine if this is a chassis node and set it's instance */
20410942STom.Pothier@Sun.COM if ((strlen(hcfmri->hc_name) == strlen(CHASSIS)) &&
20510942STom.Pothier@Sun.COM strncmp(hcfmri->hc_name, CHASSIS, strlen(CHASSIS)) == 0) {
20610942STom.Pothier@Sun.COM is_chassis = 1;
20710942STom.Pothier@Sun.COM chassis_instance = hcfmri->instance;
20810942STom.Pothier@Sun.COM }
20910942STom.Pothier@Sun.COM
21010942STom.Pothier@Sun.COM /*
21110942STom.Pothier@Sun.COM * Set the authority data, inheriting it if possible, but creating it
21210942STom.Pothier@Sun.COM * if necessary.
21310942STom.Pothier@Sun.COM */
21410942STom.Pothier@Sun.COM
21510942STom.Pothier@Sun.COM /* product-id */
21610942STom.Pothier@Sun.COM result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY,
21710942STom.Pothier@Sun.COM FM_FMRI_AUTH_PRODUCT, &err);
21810942STom.Pothier@Sun.COM if (result != 0 && err != ETOPO_PROP_DEFD) {
21910942STom.Pothier@Sun.COM result = nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT,
22010942STom.Pothier@Sun.COM &prod);
22110942STom.Pothier@Sun.COM if (result != 0 || prod == NULL) {
22210942STom.Pothier@Sun.COM /*
22310942STom.Pothier@Sun.COM * No product information in the parent node or auth
22410942STom.Pothier@Sun.COM * list. Use the product information in the hcfrmi
22510942STom.Pothier@Sun.COM * struct.
22610942STom.Pothier@Sun.COM */
22710942STom.Pothier@Sun.COM prod = (char *)hcfmri->product;
22810942STom.Pothier@Sun.COM if (prod == NULL) {
22910942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: product name not "
23010942STom.Pothier@Sun.COM "found for %s node\n", f, hcfmri->hc_name);
23110942STom.Pothier@Sun.COM }
23210942STom.Pothier@Sun.COM }
23310942STom.Pothier@Sun.COM
23410942STom.Pothier@Sun.COM /*
23510942STom.Pothier@Sun.COM * We continue even if the product information is not available
23610942STom.Pothier@Sun.COM * to enumerate as much as possible.
23710942STom.Pothier@Sun.COM */
23810942STom.Pothier@Sun.COM if (prod != NULL) {
23910942STom.Pothier@Sun.COM result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY,
24010942STom.Pothier@Sun.COM FM_FMRI_AUTH_PRODUCT, TOPO_PROP_IMMUTABLE, prod,
24110942STom.Pothier@Sun.COM &err);
24210942STom.Pothier@Sun.COM if (result != 0) {
24310942STom.Pothier@Sun.COM /* Preserve the error and continue */
24410983STom.Pothier@Sun.COM (void) topo_mod_seterrno(mod, err);
24510942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: failed to set "
24610942STom.Pothier@Sun.COM "property %s (%d) : %s\n", f,
24710942STom.Pothier@Sun.COM FM_FMRI_AUTH_PRODUCT, err,
24810942STom.Pothier@Sun.COM topo_strerror(err));
24910942STom.Pothier@Sun.COM }
25010942STom.Pothier@Sun.COM }
25110942STom.Pothier@Sun.COM }
25210942STom.Pothier@Sun.COM
25310942STom.Pothier@Sun.COM /* product-sn */
25410942STom.Pothier@Sun.COM result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY,
25510942STom.Pothier@Sun.COM FM_FMRI_AUTH_PRODUCT_SN, &err);
25610942STom.Pothier@Sun.COM if (result != 0 && err != ETOPO_PROP_DEFD) {
25710942STom.Pothier@Sun.COM result = nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN,
25810942STom.Pothier@Sun.COM &psn);
25910942STom.Pothier@Sun.COM if (result != 0 || psn == NULL) {
26010942STom.Pothier@Sun.COM /*
26110942STom.Pothier@Sun.COM * No product-sn information in the parent node or auth
26210942STom.Pothier@Sun.COM * list.
26310942STom.Pothier@Sun.COM */
26410942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: psn not found\n", f);
26510942STom.Pothier@Sun.COM } else {
26610942STom.Pothier@Sun.COM /*
26710942STom.Pothier@Sun.COM * We continue even if the product-sn information is
26810942STom.Pothier@Sun.COM * not available to enumerate as much as possible.
26910942STom.Pothier@Sun.COM */
27010942STom.Pothier@Sun.COM result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY,
27110942STom.Pothier@Sun.COM FM_FMRI_AUTH_PRODUCT_SN, TOPO_PROP_IMMUTABLE, psn,
27210942STom.Pothier@Sun.COM &err);
27310942STom.Pothier@Sun.COM if (result != 0) {
27410942STom.Pothier@Sun.COM /* Preserve the error and continue */
27510983STom.Pothier@Sun.COM (void) topo_mod_seterrno(mod, err);
27610942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: failed to "
27710942STom.Pothier@Sun.COM "set property %s (%d) : %s\n", f,
27810942STom.Pothier@Sun.COM FM_FMRI_AUTH_PRODUCT_SN, err,
27910942STom.Pothier@Sun.COM topo_strerror(err));
28010942STom.Pothier@Sun.COM }
28110942STom.Pothier@Sun.COM }
28210942STom.Pothier@Sun.COM }
28310942STom.Pothier@Sun.COM
28410942STom.Pothier@Sun.COM /* chassis-id */
28510942STom.Pothier@Sun.COM if (is_chassis == 0 || (is_chassis == 1 && chassis_instance == 0)) {
28610942STom.Pothier@Sun.COM /* either not a chassis node, or chassis #0 */
28710942STom.Pothier@Sun.COM result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY,
28810942STom.Pothier@Sun.COM FM_FMRI_AUTH_CHASSIS, &err);
28910942STom.Pothier@Sun.COM } else {
29010942STom.Pothier@Sun.COM /* chassis 'n' in a >1 chassis system */
29110942STom.Pothier@Sun.COM result = err = -1;
29210942STom.Pothier@Sun.COM }
29310942STom.Pothier@Sun.COM if (result != 0 && err != ETOPO_PROP_DEFD) {
29410942STom.Pothier@Sun.COM if (is_chassis == 0) {
29510942STom.Pothier@Sun.COM result = nvlist_lookup_string(auth,
29610942STom.Pothier@Sun.COM FM_FMRI_AUTH_CHASSIS, &csn);
29710942STom.Pothier@Sun.COM if (result != 0 || csn == NULL) {
29810942STom.Pothier@Sun.COM /*
29910942STom.Pothier@Sun.COM * No chassis information in the parent
30010942STom.Pothier@Sun.COM * node or auth list.
30110942STom.Pothier@Sun.COM */
30210942STom.Pothier@Sun.COM topo_mod_dprintf(mod,
30310942STom.Pothier@Sun.COM "%s: csn name not found\n", f);
30410942STom.Pothier@Sun.COM }
30510942STom.Pothier@Sun.COM } else {
30610942STom.Pothier@Sun.COM /*
30710942STom.Pothier@Sun.COM * So as not to blindly set the chassis-id to
30810942STom.Pothier@Sun.COM * chassis #0's serial number.
30910942STom.Pothier@Sun.COM */
31010942STom.Pothier@Sun.COM csn = val = topo_mod_strdup(mod, hcfmri->serial_number);
31110942STom.Pothier@Sun.COM }
31210942STom.Pothier@Sun.COM
31310942STom.Pothier@Sun.COM /*
31410942STom.Pothier@Sun.COM * We continue even if the chassis information is not available
31510942STom.Pothier@Sun.COM * to enumerate as much as possible.
31610942STom.Pothier@Sun.COM */
31710942STom.Pothier@Sun.COM if (csn != NULL) {
31810942STom.Pothier@Sun.COM if (is_chassis == 1)
31910942STom.Pothier@Sun.COM result = topo_prop_set_string(t_node,
32010942STom.Pothier@Sun.COM FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS,
32110942STom.Pothier@Sun.COM TOPO_PROP_MUTABLE, csn, &err);
32210942STom.Pothier@Sun.COM else
32310942STom.Pothier@Sun.COM result = topo_prop_set_string(t_node,
32410942STom.Pothier@Sun.COM FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS,
32510942STom.Pothier@Sun.COM TOPO_PROP_IMMUTABLE, csn, &err);
32610942STom.Pothier@Sun.COM
32710942STom.Pothier@Sun.COM if (result != 0) {
32810942STom.Pothier@Sun.COM /* Preserve the error and continue */
32910983STom.Pothier@Sun.COM (void) topo_mod_seterrno(mod, err);
33010942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: failed to "
33110942STom.Pothier@Sun.COM "set property %s (%d) : %s\n", f,
33210942STom.Pothier@Sun.COM FM_FMRI_AUTH_CHASSIS, err,
33310942STom.Pothier@Sun.COM topo_strerror(err));
33410942STom.Pothier@Sun.COM }
33510942STom.Pothier@Sun.COM }
33610942STom.Pothier@Sun.COM
33710942STom.Pothier@Sun.COM if (val != NULL) {
33810942STom.Pothier@Sun.COM topo_mod_strfree(mod, val);
33910942STom.Pothier@Sun.COM val = NULL;
34010942STom.Pothier@Sun.COM }
34110942STom.Pothier@Sun.COM }
34210942STom.Pothier@Sun.COM
34310942STom.Pothier@Sun.COM /* server-id */
34410942STom.Pothier@Sun.COM result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY,
34510942STom.Pothier@Sun.COM FM_FMRI_AUTH_SERVER, &err);
34610942STom.Pothier@Sun.COM if (result != 0 && err != ETOPO_PROP_DEFD) {
34710942STom.Pothier@Sun.COM result = nvlist_lookup_string(auth, FM_FMRI_AUTH_SERVER,
34810942STom.Pothier@Sun.COM &server);
34910942STom.Pothier@Sun.COM if (result != 0 || server == NULL) {
35010942STom.Pothier@Sun.COM /*
35110942STom.Pothier@Sun.COM * No server information in the parent node or auth
35210942STom.Pothier@Sun.COM * list. Find the server information in hostname.
35310942STom.Pothier@Sun.COM */
35410942STom.Pothier@Sun.COM server = val = x86pi_get_serverid(mod);
35510942STom.Pothier@Sun.COM if (server == NULL) {
35610942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: server "
35710942STom.Pothier@Sun.COM "name not found for %s node\n", f,
35810942STom.Pothier@Sun.COM hcfmri->hc_name);
35910942STom.Pothier@Sun.COM }
36010942STom.Pothier@Sun.COM }
36110942STom.Pothier@Sun.COM
36210942STom.Pothier@Sun.COM /*
36310942STom.Pothier@Sun.COM * We continue even if the server information is not available
36410942STom.Pothier@Sun.COM * to enumerate as much as possible.
36510942STom.Pothier@Sun.COM */
36610942STom.Pothier@Sun.COM if (server != NULL) {
36710942STom.Pothier@Sun.COM result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY,
36810942STom.Pothier@Sun.COM FM_FMRI_AUTH_SERVER, TOPO_PROP_IMMUTABLE, server,
36910942STom.Pothier@Sun.COM &err);
37010942STom.Pothier@Sun.COM if (result != 0) {
37110942STom.Pothier@Sun.COM /* Preserve the error and continue */
37210983STom.Pothier@Sun.COM (void) topo_mod_seterrno(mod, err);
37310942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: failed to "
37410942STom.Pothier@Sun.COM "set property %s (%d) : %s\n", f,
37510942STom.Pothier@Sun.COM FM_FMRI_AUTH_SERVER, err,
37610942STom.Pothier@Sun.COM topo_strerror(err));
37710942STom.Pothier@Sun.COM }
37810942STom.Pothier@Sun.COM }
37910942STom.Pothier@Sun.COM
38010942STom.Pothier@Sun.COM if (val != NULL)
38110942STom.Pothier@Sun.COM topo_mod_strfree(mod, val);
38210942STom.Pothier@Sun.COM }
38310942STom.Pothier@Sun.COM
38410942STom.Pothier@Sun.COM nvlist_free(auth);
38510942STom.Pothier@Sun.COM
38610942STom.Pothier@Sun.COM return (0);
38710942STom.Pothier@Sun.COM }
38810942STom.Pothier@Sun.COM
38910942STom.Pothier@Sun.COM
39010942STom.Pothier@Sun.COM /*
39110942STom.Pothier@Sun.COM * Calculate a generic FRU for the given node. If the node is not a FRU,
39210942STom.Pothier@Sun.COM * then inherit the FRU data from the nodes parent.
39310942STom.Pothier@Sun.COM */
39410942STom.Pothier@Sun.COM int
x86pi_set_frufmri(topo_mod_t * mod,x86pi_hcfmri_t * hcfmri,tnode_t * t_parent,tnode_t * t_node,int flag)39510942STom.Pothier@Sun.COM x86pi_set_frufmri(topo_mod_t *mod, x86pi_hcfmri_t *hcfmri, tnode_t *t_parent,
39610942STom.Pothier@Sun.COM tnode_t *t_node, int flag)
39710942STom.Pothier@Sun.COM {
39810942STom.Pothier@Sun.COM int result;
39910942STom.Pothier@Sun.COM int err;
40010942STom.Pothier@Sun.COM
40110942STom.Pothier@Sun.COM nvlist_t *auth = NULL;
40210942STom.Pothier@Sun.COM nvlist_t *frufmri = NULL;
40310942STom.Pothier@Sun.COM
40410942STom.Pothier@Sun.COM if (t_node == NULL || mod == NULL) {
40510942STom.Pothier@Sun.COM return (-1);
40610942STom.Pothier@Sun.COM }
40710942STom.Pothier@Sun.COM
40810942STom.Pothier@Sun.COM /*
40910942STom.Pothier@Sun.COM * Determine if this node is a FRU
41010942STom.Pothier@Sun.COM */
41110942STom.Pothier@Sun.COM if (!(flag & X86PI_ENUM_FRU)) {
41210942STom.Pothier@Sun.COM /* This node is not a FRU. Inherit from parent and return */
41310983STom.Pothier@Sun.COM (void) topo_node_fru_set(t_node, NULL, 0, &result);
41410942STom.Pothier@Sun.COM return (0);
41510942STom.Pothier@Sun.COM }
41610942STom.Pothier@Sun.COM
41710942STom.Pothier@Sun.COM /*
41810942STom.Pothier@Sun.COM * This node is a FRU. Create an FMRI.
41910942STom.Pothier@Sun.COM */
42010942STom.Pothier@Sun.COM auth = topo_mod_auth(mod, t_parent);
42110942STom.Pothier@Sun.COM frufmri = topo_mod_hcfmri(mod, t_parent, FM_HC_SCHEME_VERSION,
42210942STom.Pothier@Sun.COM hcfmri->hc_name, hcfmri->instance, NULL, auth,
42310942STom.Pothier@Sun.COM hcfmri->part_number, hcfmri->version, hcfmri->serial_number);
42410942STom.Pothier@Sun.COM if (frufmri == NULL) {
42510942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "failed to create FRU: %s\n",
42610942STom.Pothier@Sun.COM topo_strerror(topo_mod_errno(mod)));
42710942STom.Pothier@Sun.COM }
42810942STom.Pothier@Sun.COM nvlist_free(auth);
42910942STom.Pothier@Sun.COM
43010942STom.Pothier@Sun.COM /* Set the FRU, whether NULL or not */
43110942STom.Pothier@Sun.COM result = topo_node_fru_set(t_node, frufmri, 0, &err);
43210942STom.Pothier@Sun.COM if (result != 0) {
43310983STom.Pothier@Sun.COM (void) topo_mod_seterrno(mod, err);
43410942STom.Pothier@Sun.COM }
43510942STom.Pothier@Sun.COM nvlist_free(frufmri);
43610942STom.Pothier@Sun.COM
43710942STom.Pothier@Sun.COM return (result);
43810942STom.Pothier@Sun.COM }
43910942STom.Pothier@Sun.COM
44010942STom.Pothier@Sun.COM
44110942STom.Pothier@Sun.COM /*
44210942STom.Pothier@Sun.COM * Set the label for a topo node.
44310942STom.Pothier@Sun.COM */
44410942STom.Pothier@Sun.COM int
x86pi_set_label(topo_mod_t * mod,const char * label,const char * name,tnode_t * t_node)44510942STom.Pothier@Sun.COM x86pi_set_label(topo_mod_t *mod, const char *label, const char *name,
44610942STom.Pothier@Sun.COM tnode_t *t_node)
44710942STom.Pothier@Sun.COM {
44810942STom.Pothier@Sun.COM int result;
44910942STom.Pothier@Sun.COM int err;
45010942STom.Pothier@Sun.COM
45110942STom.Pothier@Sun.COM if (mod == NULL) {
45210942STom.Pothier@Sun.COM return (-1);
45310942STom.Pothier@Sun.COM }
45410942STom.Pothier@Sun.COM
45510942STom.Pothier@Sun.COM /*
45610942STom.Pothier@Sun.COM * Set the label for this topology node.
45710942STom.Pothier@Sun.COM * Note that a NULL label will inherit the label from topology
45810942STom.Pothier@Sun.COM * node's parent.
45910942STom.Pothier@Sun.COM */
46010942STom.Pothier@Sun.COM result = topo_node_label_set(t_node, (char *)label, &err);
46110942STom.Pothier@Sun.COM if (result != 0) {
46210983STom.Pothier@Sun.COM (void) topo_mod_seterrno(mod, err);
46310942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "x86pi_set_label: failed with label %s "
46410942STom.Pothier@Sun.COM "on %s node: %s\n", (label == NULL ? "NULL" : label),
46510942STom.Pothier@Sun.COM name, topo_strerror(err));
46610942STom.Pothier@Sun.COM }
46710942STom.Pothier@Sun.COM
46810942STom.Pothier@Sun.COM return (result);
46910942STom.Pothier@Sun.COM }
47010942STom.Pothier@Sun.COM
47110942STom.Pothier@Sun.COM
47210942STom.Pothier@Sun.COM /*
47310942STom.Pothier@Sun.COM * Calculate the system information for a node. Inherit the data if
47410942STom.Pothier@Sun.COM * possible, but always create an appropriate property group.
47510942STom.Pothier@Sun.COM */
47610942STom.Pothier@Sun.COM int
x86pi_set_system(topo_mod_t * mod,tnode_t * t_node)47710942STom.Pothier@Sun.COM x86pi_set_system(topo_mod_t *mod, tnode_t *t_node)
47810942STom.Pothier@Sun.COM {
47910942STom.Pothier@Sun.COM int result;
48010942STom.Pothier@Sun.COM int err;
48110942STom.Pothier@Sun.COM struct utsname uts;
48210942STom.Pothier@Sun.COM char isa[MAXNAMELEN];
48310942STom.Pothier@Sun.COM
48410942STom.Pothier@Sun.COM if (mod == NULL || t_node == NULL) {
48510942STom.Pothier@Sun.COM return (-1);
48610942STom.Pothier@Sun.COM }
48710942STom.Pothier@Sun.COM
48810942STom.Pothier@Sun.COM result = topo_pgroup_create(t_node, &sys_pgroup, &err);
48910942STom.Pothier@Sun.COM if (result != 0 && err != ETOPO_PROP_DEFD) {
49010942STom.Pothier@Sun.COM /*
49110942STom.Pothier@Sun.COM * We failed to create the property group and it was not
49210942STom.Pothier@Sun.COM * already defined. Set the err code and return failure.
49310942STom.Pothier@Sun.COM */
49410983STom.Pothier@Sun.COM (void) topo_mod_seterrno(mod, err);
49510942STom.Pothier@Sun.COM return (-1);
49610942STom.Pothier@Sun.COM }
49710942STom.Pothier@Sun.COM
49810942STom.Pothier@Sun.COM result = topo_prop_inherit(t_node, TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA,
49910942STom.Pothier@Sun.COM &err);
50010942STom.Pothier@Sun.COM if (result != 0 && err != ETOPO_PROP_DEFD) {
50110942STom.Pothier@Sun.COM isa[0] = '\0';
50210942STom.Pothier@Sun.COM result = sysinfo(SI_ARCHITECTURE, isa, sizeof (isa));
50310942STom.Pothier@Sun.COM if (result == -1) {
50410942STom.Pothier@Sun.COM /* Preserve the error and continue */
50510942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "x86pi_set_system: failed to "
50610942STom.Pothier@Sun.COM "read SI_ARCHITECTURE: %d\n", errno);
50710942STom.Pothier@Sun.COM }
50810942STom.Pothier@Sun.COM if (strnlen(isa, MAXNAMELEN) > 0) {
50910942STom.Pothier@Sun.COM result = topo_prop_set_string(t_node,
51010942STom.Pothier@Sun.COM TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA,
51110942STom.Pothier@Sun.COM TOPO_PROP_IMMUTABLE, isa, &err);
51210942STom.Pothier@Sun.COM if (result != 0) {
51310942STom.Pothier@Sun.COM /* Preserve the error and continue */
51410983STom.Pothier@Sun.COM (void) topo_mod_seterrno(mod, err);
51510942STom.Pothier@Sun.COM topo_mod_dprintf(mod,
51610942STom.Pothier@Sun.COM "x86pi_set_auth: failed to "
51710942STom.Pothier@Sun.COM "set property %s (%d) : %s\n",
51810942STom.Pothier@Sun.COM TOPO_PROP_ISA, err, topo_strerror(err));
51910942STom.Pothier@Sun.COM }
52010942STom.Pothier@Sun.COM }
52110942STom.Pothier@Sun.COM }
52210942STom.Pothier@Sun.COM
52310942STom.Pothier@Sun.COM result = topo_prop_inherit(t_node, TOPO_PGROUP_SYSTEM,
52410942STom.Pothier@Sun.COM TOPO_PROP_MACHINE, &err);
52510942STom.Pothier@Sun.COM if (result != 0 && err != ETOPO_PROP_DEFD) {
52610942STom.Pothier@Sun.COM result = uname(&uts);
52710942STom.Pothier@Sun.COM if (result == -1) {
52810942STom.Pothier@Sun.COM /* Preserve the error and continue */
52910983STom.Pothier@Sun.COM (void) topo_mod_seterrno(mod, errno);
53010942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "x86pi_set_system: failed to "
53110942STom.Pothier@Sun.COM "read uname: %d\n", errno);
53210942STom.Pothier@Sun.COM }
53310942STom.Pothier@Sun.COM if (strnlen(uts.machine, sizeof (uts.machine)) > 0) {
53410942STom.Pothier@Sun.COM result = topo_prop_set_string(t_node,
53510942STom.Pothier@Sun.COM TOPO_PGROUP_SYSTEM, TOPO_PROP_MACHINE,
53610942STom.Pothier@Sun.COM TOPO_PROP_IMMUTABLE, uts.machine, &err);
53710942STom.Pothier@Sun.COM if (result != 0) {
53810942STom.Pothier@Sun.COM /* Preserve the error and continue */
53910983STom.Pothier@Sun.COM (void) topo_mod_seterrno(mod, err);
54010942STom.Pothier@Sun.COM topo_mod_dprintf(mod,
54110942STom.Pothier@Sun.COM "x86pi_set_auth: failed to "
54210942STom.Pothier@Sun.COM "set property %s (%d) : %s\n",
54310942STom.Pothier@Sun.COM TOPO_PROP_MACHINE, err, topo_strerror(err));
54410942STom.Pothier@Sun.COM }
54510942STom.Pothier@Sun.COM }
54610942STom.Pothier@Sun.COM }
54710942STom.Pothier@Sun.COM
54810942STom.Pothier@Sun.COM return (0);
54910942STom.Pothier@Sun.COM }
55010942STom.Pothier@Sun.COM
55110942STom.Pothier@Sun.COM /*
55210942STom.Pothier@Sun.COM * All the checks for compatibility are done within the kernel where the
55310942STom.Pothier@Sun.COM * ereport generators are. They'll determine first if there's a problem
55410942STom.Pothier@Sun.COM * and the topo enum will follow suit. The /dev/fm ioclt returns the value
55510942STom.Pothier@Sun.COM * of the x86gentopo_legacy kernel variable which determines if this platform
55610942STom.Pothier@Sun.COM * will provide an x86 generic topo or legacy topo enumeration.
55710942STom.Pothier@Sun.COM */
55810942STom.Pothier@Sun.COM /* ARGSUSED */
55910942STom.Pothier@Sun.COM int
x86pi_check_comp(topo_mod_t * mod)560*12832STrang.Do@Sun.COM x86pi_check_comp(topo_mod_t *mod)
56110942STom.Pothier@Sun.COM {
56210942STom.Pothier@Sun.COM int rv;
56310942STom.Pothier@Sun.COM int fd;
56410942STom.Pothier@Sun.COM int32_t legacy;
56510942STom.Pothier@Sun.COM nvlist_t *nvl = NULL;
56610942STom.Pothier@Sun.COM fm_ioc_data_t fid;
56710942STom.Pothier@Sun.COM char *ibuf = NULL, *obuf = NULL;
56810942STom.Pothier@Sun.COM size_t insz = 0, outsz = 0;
56910942STom.Pothier@Sun.COM char *f = "x86pi_check_comp";
570*12832STrang.Do@Sun.COM smbios_hdl_t *shp;
571*12832STrang.Do@Sun.COM
572*12832STrang.Do@Sun.COM shp = topo_mod_smbios(mod);
573*12832STrang.Do@Sun.COM if (shp == NULL)
574*12832STrang.Do@Sun.COM return (X86PI_NONE);
57510942STom.Pothier@Sun.COM
57610942STom.Pothier@Sun.COM /* open /dev/fm */
57710942STom.Pothier@Sun.COM fd = open("/dev/fm", O_RDONLY);
57810942STom.Pothier@Sun.COM if (fd < 0) {
57910942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: failed to open /dev/fm.\n", f);
58010942STom.Pothier@Sun.COM return (X86PI_NONE);
58110942STom.Pothier@Sun.COM }
58210942STom.Pothier@Sun.COM
58310942STom.Pothier@Sun.COM /* set up buffers and ioctl data structure */
58410942STom.Pothier@Sun.COM outsz = FM_IOC_MAXBUFSZ;
58510942STom.Pothier@Sun.COM obuf = topo_mod_alloc(mod, outsz);
58610942STom.Pothier@Sun.COM if (obuf == NULL) {
58710942STom.Pothier@Sun.COM perror("umem_alloc");
58810942STom.Pothier@Sun.COM return (X86PI_NONE);
58910942STom.Pothier@Sun.COM }
59010942STom.Pothier@Sun.COM
59110942STom.Pothier@Sun.COM fid.fid_version = 1;
59210942STom.Pothier@Sun.COM fid.fid_insz = insz;
59310942STom.Pothier@Sun.COM fid.fid_inbuf = ibuf;
59410942STom.Pothier@Sun.COM fid.fid_outsz = outsz;
59510942STom.Pothier@Sun.COM fid.fid_outbuf = obuf;
59610942STom.Pothier@Sun.COM
59710942STom.Pothier@Sun.COM /* send the ioctl to /dev/fm to retrieve legacy variable */
59810942STom.Pothier@Sun.COM rv = ioctl(fd, FM_IOC_GENTOPO_LEGACY, &fid);
59910942STom.Pothier@Sun.COM if (rv < 0) {
60010942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: ioctl to /dev/fm failed", f);
60110942STom.Pothier@Sun.COM perror("fm_ioctl");
60210942STom.Pothier@Sun.COM (void) close(fd);
60310942STom.Pothier@Sun.COM return (X86PI_NONE);
60410942STom.Pothier@Sun.COM }
60510942STom.Pothier@Sun.COM (void) close(fd);
60610942STom.Pothier@Sun.COM
60710942STom.Pothier@Sun.COM (void) nvlist_unpack(fid.fid_outbuf, fid.fid_outsz, &nvl, 0);
60810942STom.Pothier@Sun.COM (void) nvlist_lookup_int32(nvl, FM_GENTOPO_LEGACY, &legacy);
60910942STom.Pothier@Sun.COM
61010942STom.Pothier@Sun.COM nvlist_free(nvl);
61110942STom.Pothier@Sun.COM topo_mod_free(mod, obuf, outsz);
61210942STom.Pothier@Sun.COM
61310942STom.Pothier@Sun.COM if (legacy == 1) {
61410942STom.Pothier@Sun.COM /* legacy kernel variable set; will do the same */
61510942STom.Pothier@Sun.COM return (X86PI_NONE);
61610942STom.Pothier@Sun.COM }
61710942STom.Pothier@Sun.COM
61810942STom.Pothier@Sun.COM /* legacy kernel variable not set; generic topo enum */
61910942STom.Pothier@Sun.COM return (X86PI_FULL);
62010942STom.Pothier@Sun.COM }
62110942STom.Pothier@Sun.COM
62210942STom.Pothier@Sun.COM const char *
x86pi_cleanup_smbios_str(topo_mod_t * mod,const char * begin,int str_type)62310942STom.Pothier@Sun.COM x86pi_cleanup_smbios_str(topo_mod_t *mod, const char *begin, int str_type)
62410942STom.Pothier@Sun.COM {
62510942STom.Pothier@Sun.COM char buf[MAXNAMELEN];
62610942STom.Pothier@Sun.COM const char *end, *cp;
62710942STom.Pothier@Sun.COM char *pp;
62810942STom.Pothier@Sun.COM char c;
62910942STom.Pothier@Sun.COM int i;
63010942STom.Pothier@Sun.COM
63110942STom.Pothier@Sun.COM end = begin + strlen(begin);
63210942STom.Pothier@Sun.COM
63310942STom.Pothier@Sun.COM while (begin < end && isspace(*begin))
63410942STom.Pothier@Sun.COM begin++;
63510942STom.Pothier@Sun.COM while (begin < end && isspace(*(end - 1)))
63610942STom.Pothier@Sun.COM end--;
63710942STom.Pothier@Sun.COM
63810942STom.Pothier@Sun.COM if (begin >= end)
63910942STom.Pothier@Sun.COM return (NULL);
64010942STom.Pothier@Sun.COM
64110942STom.Pothier@Sun.COM cp = begin;
64210942STom.Pothier@Sun.COM for (i = 0; i < MAXNAMELEN - 1; i++) {
64310942STom.Pothier@Sun.COM if (cp >= end)
64410942STom.Pothier@Sun.COM break;
64510942STom.Pothier@Sun.COM c = *cp;
64610942STom.Pothier@Sun.COM if (str_type == LABEL) {
64710942STom.Pothier@Sun.COM if (!isprint(c))
64810942STom.Pothier@Sun.COM buf[i] = '-';
64910942STom.Pothier@Sun.COM else
65010942STom.Pothier@Sun.COM buf[i] = c;
65110942STom.Pothier@Sun.COM } else {
65210942STom.Pothier@Sun.COM if (c == ':' || c == '=' || c == '/' ||
65310942STom.Pothier@Sun.COM isspace(c) || !isprint(c))
65410942STom.Pothier@Sun.COM buf[i] = '-';
65510942STom.Pothier@Sun.COM else
65610942STom.Pothier@Sun.COM buf[i] = c;
65710942STom.Pothier@Sun.COM }
65810942STom.Pothier@Sun.COM cp++;
65910942STom.Pothier@Sun.COM }
66010942STom.Pothier@Sun.COM buf[i] = 0;
66110942STom.Pothier@Sun.COM
66210942STom.Pothier@Sun.COM pp = topo_mod_strdup(mod, buf);
66310942STom.Pothier@Sun.COM
66410942STom.Pothier@Sun.COM if (str_type == LABEL)
66510942STom.Pothier@Sun.COM topo_mod_strfree(mod, (char *)begin);
66610942STom.Pothier@Sun.COM
66710942STom.Pothier@Sun.COM return (pp);
66810942STom.Pothier@Sun.COM }
66911859STom.Pothier@Sun.COM
67011859STom.Pothier@Sun.COM /*
67111859STom.Pothier@Sun.COM * Return Bus/Dev/Func from "reg" devinfo property.
67211859STom.Pothier@Sun.COM */
67311859STom.Pothier@Sun.COM uint16_t
x86pi_bdf(topo_mod_t * mod,di_node_t node)67411859STom.Pothier@Sun.COM x86pi_bdf(topo_mod_t *mod, di_node_t node)
67511859STom.Pothier@Sun.COM {
67611859STom.Pothier@Sun.COM int *val;
67711859STom.Pothier@Sun.COM
67811859STom.Pothier@Sun.COM if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "reg", &val) < 0) {
67911859STom.Pothier@Sun.COM topo_mod_dprintf(mod, "couldn't get \"reg\" prop: %s.\n",
68011859STom.Pothier@Sun.COM strerror(errno));
68111859STom.Pothier@Sun.COM return ((uint16_t)-1);
68211859STom.Pothier@Sun.COM }
68311859STom.Pothier@Sun.COM
68411859STom.Pothier@Sun.COM return (uint16_t)((*val & PCI_REG_BDFR_M) >> PCI_REG_FUNC_SHIFT);
68511859STom.Pothier@Sun.COM }
68611859STom.Pothier@Sun.COM
68711859STom.Pothier@Sun.COM /*
68811859STom.Pothier@Sun.COM * Return PHY from "sata-phy" devinfo proporty.
68911859STom.Pothier@Sun.COM */
69011859STom.Pothier@Sun.COM int
x86pi_phy(topo_mod_t * mod,di_node_t node)69111859STom.Pothier@Sun.COM x86pi_phy(topo_mod_t *mod, di_node_t node)
69211859STom.Pothier@Sun.COM {
69311859STom.Pothier@Sun.COM int *phy;
69411859STom.Pothier@Sun.COM
69511859STom.Pothier@Sun.COM if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "sata-phy", &phy) < 0) {
69611859STom.Pothier@Sun.COM topo_mod_dprintf(mod, "couldn't get \"sata-phy\" prop: %s.\n",
69711859STom.Pothier@Sun.COM strerror(errno));
69811859STom.Pothier@Sun.COM return (-1);
69911859STom.Pothier@Sun.COM }
70011859STom.Pothier@Sun.COM
70111859STom.Pothier@Sun.COM return (*phy);
70211859STom.Pothier@Sun.COM }
703