summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/smbios/smbios.c117
-rw-r--r--usr/src/common/smbios/smb_info.c54
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/topo_hc.h5
-rw-r--r--usr/src/lib/fm/topo/modules/common/disk/disk.h12
-rw-r--r--usr/src/lib/fm/topo/modules/i86pc/x86pi/Makefile4
-rw-r--r--usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi.c43
-rw-r--r--usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_bay.c350
-rw-r--r--usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_hostbridge.c16
-rw-r--r--usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_impl.h8
-rw-r--r--usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_subr.c37
-rw-r--r--usr/src/lib/libsmbios/common/mapfile-vers4
-rw-r--r--usr/src/uts/common/io/sata/impl/sata.c13
-rw-r--r--usr/src/uts/common/sys/smbios.h34
-rw-r--r--usr/src/uts/common/sys/smbios_impl.h24
14 files changed, 652 insertions, 69 deletions
diff --git a/usr/src/cmd/smbios/smbios.c b/usr/src/cmd/smbios/smbios.c
index 6ecde1ef11..a66dcaf593 100644
--- a/usr/src/cmd/smbios/smbios.c
+++ b/usr/src/cmd/smbios/smbios.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -139,6 +139,39 @@ id_printf(FILE *fp, const char *s, id_t id)
}
}
+static int
+check_oem(smbios_hdl_t *shp)
+{
+ int i;
+ int cnt;
+ int rv;
+ id_t oem_id;
+ smbios_struct_t s;
+ const char **oem_str;
+
+ rv = smbios_lookup_type(shp, SMB_TYPE_OEMSTR, &s);
+ if (rv != 0) {
+ return (-1);
+ }
+
+ oem_id = s.smbstr_id;
+
+ cnt = smbios_info_strtab(shp, oem_id, 0, NULL);
+ if (cnt > 0) {
+ oem_str = alloca(sizeof (char *) * cnt);
+ (void) smbios_info_strtab(shp, oem_id, cnt, oem_str);
+
+ for (i = 0; i < cnt; i++) {
+ if (strncmp(oem_str[i], SMB_PRMS1,
+ strlen(SMB_PRMS1) + 1) == 0) {
+ return (0);
+ }
+ }
+ }
+
+ return (-1);
+}
+
static void
print_smbios(smbios_hdl_t *shp, FILE *fp)
{
@@ -489,8 +522,10 @@ static void
print_slot(smbios_hdl_t *shp, id_t id, FILE *fp)
{
smbios_slot_t s;
+ smbios_entry_t e;
(void) smbios_info_slot(shp, id, &s);
+ (void) smbios_info_smbios(shp, &e);
oprintf(fp, " Reference Designator: %s\n", s.smbl_name);
oprintf(fp, " Slot ID: 0x%x\n", s.smbl_id);
@@ -514,6 +549,28 @@ print_slot(smbios_hdl_t *shp, id_t id, FILE *fp)
flag_printf(fp, "Slot Characteristics 2",
s.smbl_ch2, sizeof (s.smbl_ch2) * NBBY,
smbios_slot_ch2_name, smbios_slot_ch2_desc);
+
+ if (check_oem(shp) != 0 && (e.smbe_major < 2 || e.smbe_minor < 6))
+ return;
+
+ oprintf(fp, " Segment Group: %u\n", s.smbl_sg);
+ oprintf(fp, " Bus Number: %u\n", s.smbl_bus);
+ oprintf(fp, " Device/Function Number: %u\n", s.smbl_df);
+}
+
+static void
+print_obdevs_ext(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_obdev_ext_t oe;
+
+ (void) smbios_info_obdevs_ext(shp, id, &oe);
+
+ oprintf(fp, " Reference Designator: %s\n", oe.smboe_name);
+ oprintf(fp, " Device Type: %u\n", oe.smboe_dtype);
+ oprintf(fp, " Device Type Instance: %u\n", oe.smboe_dti);
+ oprintf(fp, " Segment Group Number: %u\n", oe.smboe_sg);
+ oprintf(fp, " Bus Number: %u\n", oe.smboe_bus);
+ oprintf(fp, " Device/Function Number: %u\n", oe.smboe_df);
}
static void
@@ -814,39 +871,6 @@ print_ipmi(smbios_hdl_t *shp, FILE *fp)
smbios_ipmi_flag_name, smbios_ipmi_flag_desc);
}
-static int
-check_oem(smbios_hdl_t *shp)
-{
- int i;
- int cnt;
- int rv;
- id_t oem_id;
- smbios_struct_t s;
- const char **oem_str;
-
- rv = smbios_lookup_type(shp, SMB_TYPE_OEMSTR, &s);
- if (rv != 0) {
- return (-1);
- }
-
- oem_id = s.smbstr_id;
-
- cnt = smbios_info_strtab(shp, oem_id, 0, NULL);
- if (cnt > 0) {
- oem_str = alloca(sizeof (char *) * cnt);
- (void) smbios_info_strtab(shp, oem_id, cnt, oem_str);
-
- for (i = 0; i < cnt; i++) {
- if (strncmp(oem_str[i], SMB_PRMS1,
- strlen(SMB_PRMS1) + 1) == 0) {
- return (0);
- }
- }
- }
-
- return (-1);
-}
-
static void
print_extprocessor(smbios_hdl_t *shp, id_t id, FILE *fp)
{
@@ -869,6 +893,23 @@ print_extprocessor(smbios_hdl_t *shp, id_t id, FILE *fp)
}
static void
+print_extport(smbios_hdl_t *shp, id_t id, FILE *fp)
+{
+ smbios_port_ext_t epo;
+
+ if (check_oem(shp) != 0)
+ return;
+
+ (void) smbios_info_extport(shp, id, &epo);
+
+ oprintf(fp, " Chassis Handle: %u\n", epo.smbporte_chassis);
+ oprintf(fp, " Port Connector Handle: %u\n", epo.smbporte_port);
+ oprintf(fp, " Device Type: %u\n", epo.smbporte_dtype);
+ oprintf(fp, " Device Handle: %u\n", epo.smbporte_devhdl);
+ oprintf(fp, " PHY: %u\n", epo.smbporte_phy);
+}
+
+static void
print_pciexrc(smbios_hdl_t *shp, id_t id, FILE *fp)
{
smbios_pciexrc_t pcie;
@@ -1037,10 +1078,18 @@ print_struct(smbios_hdl_t *shp, const smbios_struct_t *sp, void *fp)
oprintf(fp, "\n");
print_ipmi(shp, fp);
break;
+ case SMB_TYPE_OBDEVEXT:
+ oprintf(fp, "\n");
+ print_obdevs_ext(shp, sp->smbstr_id, fp);
+ break;
case SUN_OEM_EXT_PROCESSOR:
oprintf(fp, "\n");
print_extprocessor(shp, sp->smbstr_id, fp);
break;
+ case SUN_OEM_EXT_PORT:
+ oprintf(fp, "\n");
+ print_extport(shp, sp->smbstr_id, fp);
+ break;
case SUN_OEM_PCIEXRC:
oprintf(fp, "\n");
print_pciexrc(shp, sp->smbstr_id, fp);
diff --git a/usr/src/common/smbios/smb_info.c b/usr/src/common/smbios/smb_info.c
index b1882c74ca..4d187075fb 100644
--- a/usr/src/common/smbios/smb_info.c
+++ b/usr/src/common/smbios/smb_info.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -551,6 +551,34 @@ smbios_info_slot(smbios_hdl_t *shp, id_t id, smbios_slot_t *sp)
sp->smbl_id = s.smbsl_id;
sp->smbl_ch1 = s.smbsl_ch1;
sp->smbl_ch2 = s.smbsl_ch2;
+ sp->smbl_sg = s.smbsl_sg;
+ sp->smbl_bus = s.smbsl_bus;
+ sp->smbl_df = s.smbsl_df;
+
+ return (0);
+}
+
+int
+smbios_info_obdevs_ext(smbios_hdl_t *shp, id_t id, smbios_obdev_ext_t *oep)
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+ smb_obdev_ext_t obe;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ if (stp->smbst_hdr->smbh_type != SMB_TYPE_OBDEVEXT)
+ return (smb_set_errno(shp, ESMB_TYPE));
+
+ smb_info_bcopy(stp->smbst_hdr, &obe, sizeof (obe));
+ bzero(oep, sizeof (smbios_obdev_ext_t));
+
+ oep->smboe_name = smb_strptr(stp, obe.smbobe_name);
+ oep->smboe_dtype = obe.smbobe_dtype;
+ oep->smboe_dti = obe.smbobe_dti;
+ oep->smboe_sg = obe.smbobe_sg;
+ oep->smboe_bus = obe.smbobe_bus;
+ oep->smboe_df = obe.smbobe_df;
return (0);
}
@@ -1005,6 +1033,30 @@ smbios_info_extprocessor(smbios_hdl_t *shp, id_t id,
}
int
+smbios_info_extport(smbios_hdl_t *shp, id_t id, smbios_port_ext_t *eportp)
+{
+ const smb_struct_t *stp = smb_lookup_id(shp, id);
+ smb_port_ext_t *ep;
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ if (stp->smbst_hdr->smbh_type != SUN_OEM_EXT_PORT)
+ return (smb_set_errno(shp, ESMB_TYPE));
+
+ ep = (smb_port_ext_t *)(uintptr_t)stp->smbst_hdr;
+ bzero(eportp, sizeof (smbios_port_ext_t));
+
+ eportp->smbporte_chassis = ep->smbpoe_chassis;
+ eportp->smbporte_port = ep->smbpoe_port;
+ eportp->smbporte_dtype = ep->smbpoe_dtype;
+ eportp->smbporte_devhdl = ep->smbpoe_devhdl;
+ eportp->smbporte_phy = ep->smbpoe_phy;
+
+ return (0);
+}
+
+int
smbios_info_pciexrc(smbios_hdl_t *shp, id_t id,
smbios_pciexrc_t *rcp)
{
diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_hc.h b/usr/src/lib/fm/topo/libtopo/common/topo_hc.h
index 8b69d3ac60..8195b66e5a 100644
--- a/usr/src/lib/fm/topo/libtopo/common/topo_hc.h
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_hc.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -106,6 +106,9 @@ extern "C" {
#define TOPO_PCI_CLASS "class-code"
#define TOPO_PCI_AADDR "assigned-addresses"
+#define TOPO_PGROUP_BINDING "binding"
+#define TOPO_BINDING_OCCUPANT "occupant-path"
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/lib/fm/topo/modules/common/disk/disk.h b/usr/src/lib/fm/topo/modules/common/disk/disk.h
index 4d64a8bec6..e87e1a9493 100644
--- a/usr/src/lib/fm/topo/modules/common/disk/disk.h
+++ b/usr/src/lib/fm/topo/modules/common/disk/disk.h
@@ -20,16 +20,15 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _DISK_H
#define _DISK_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <fm/topo_mod.h>
+#include <fm/topo_hc.h>
#include <libdevinfo.h>
#ifdef __cplusplus
@@ -51,13 +50,6 @@ extern "C" {
#define TOPO_STORAGE_FIRMWARE_REV "firmware-revision"
#define TOPO_STORAGE_CAPACITY "capacity-in-bytes"
-/*
- * Properties for binding group: The binding group required in platform
- * specific xml that describes 'bay' nodes containing internal disks.
- */
-#define TOPO_PGROUP_BINDING "binding"
-#define TOPO_BINDING_OCCUPANT "occupant-path"
-
struct topo_list;
/* Methods shared with the ses module (disk_common.c) */
diff --git a/usr/src/lib/fm/topo/modules/i86pc/x86pi/Makefile b/usr/src/lib/fm/topo/modules/i86pc/x86pi/Makefile
index 1f6b0985e5..acaf762aa3 100644
--- a/usr/src/lib/fm/topo/modules/i86pc/x86pi/Makefile
+++ b/usr/src/lib/fm/topo/modules/i86pc/x86pi/Makefile
@@ -20,7 +20,7 @@
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -33,7 +33,7 @@ TOPODIR = ../../../libtopo/common
UTILDIR = ../../common/pcibus
BRDIR = ../../common/hostbridge
UTILSRCS = did.c did_hash.c did_props.c
-X86PISRCS = x86pi.c x86pi_bboard.c x86pi_chassis.c \
+X86PISRCS = x86pi.c x86pi_bay.c x86pi_bboard.c x86pi_chassis.c \
x86pi_generic.c x86pi_hostbridge.c x86pi_subr.c
MODULESRCS = $(X86PISRCS) $(UTILSRCS)
diff --git a/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi.c b/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi.c
index 634f6c9830..7e31201655 100644
--- a/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi.c
+++ b/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -253,8 +253,10 @@ x86pi_enum_gentopo(topo_mod_t *mod, tnode_t *t_parent, smbios_hdl_t *shp)
int bb_count, ch_count;
int min, max;
int ch_inst = 0;
+ int disk_inst = 0;
topo_instance_t hbri = 0, rci = 0;
smbios_pciexrc_t hbr;
+ smbios_port_ext_t export;
char *f = "x86pi_enum_gentopo";
if (t_parent == NULL) {
@@ -301,6 +303,45 @@ x86pi_enum_gentopo(topo_mod_t *mod, tnode_t *t_parent, smbios_hdl_t *shp)
continue;
}
stypes[SMB_TYPE_CHASSIS].ids[nch].node = chassis_node;
+
+ /* count SMBIOS extended port connector structures */
+ smbc = &stypes[SUN_OEM_EXT_PORT];
+ smbc->type = SUN_OEM_EXT_PORT;
+ x86pi_smb_strcnt(shp, smbc);
+
+ /* enumerate direct attached SATA disks */
+ rv = topo_node_range_create(mod, chassis_node, BAY, 0,
+ smbc->count + 1);
+ if (rv != 0) {
+ topo_mod_dprintf(mod,
+ "%s: Failed to create %s range: %s\n",
+ f, BAY, topo_mod_errmsg(mod));
+ continue;
+ }
+
+ for (i = 0; i < smbc->count; i++) {
+ if (smbios_info_extport(shp, smbc->ids[i].id,
+ &export) != 0) {
+ topo_mod_dprintf(mod,
+ "smbios_info_export failed: id = %d\n",
+ (int)smbc->ids[i].id);
+ continue;
+ }
+ if (export.smbporte_chassis != ch_smbid)
+ continue;
+
+ /*
+ * x86pi_gen_bay:
+ * create "bay" node
+ * call "disk" enum passing in "bay" node
+ */
+ rv = x86pi_gen_bay(mod, chassis_node, shp,
+ &export, disk_inst);
+ if (rv != 0)
+ topo_mod_dprintf(mod,
+ "Failed to create disk %d\n", i);
+ disk_inst++;
+ }
}
/*
diff --git a/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_bay.c b/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_bay.c
new file mode 100644
index 0000000000..1a1669300e
--- /dev/null
+++ b/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_bay.c
@@ -0,0 +1,350 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Create bay topology node from SMBIOS Type 136 structure, call the disk
+ * enumerator to enumerate a SATA direct attached disk.
+ */
+
+#include <sys/types.h>
+#include <strings.h>
+#include <fm/topo_mod.h>
+#include <fm/topo_hc.h>
+#include <sys/systeminfo.h>
+#include <sys/smbios_impl.h>
+#include <x86pi_impl.h>
+
+#define DEVICES "/devices"
+#define HBA_DRV_NAME "ahci"
+
+#define BDF(b, df) ((uint16_t)((((uint16_t)(b) << 8) & 0xFF00) | \
+ ((uint16_t)(df) & 0x00FF)));
+
+static const topo_pgroup_info_t io_pgroup = {
+ TOPO_PGROUP_IO,
+ TOPO_STABILITY_PRIVATE,
+ TOPO_STABILITY_PRIVATE,
+ 1
+};
+
+static const topo_pgroup_info_t binding_pgroup = {
+ TOPO_PGROUP_BINDING,
+ TOPO_STABILITY_PRIVATE,
+ TOPO_STABILITY_PRIVATE,
+ 1
+};
+
+/*
+ * Return PCI Bus/Dev/Func
+ */
+int
+bay_bdf(topo_mod_t *mod, smbios_hdl_t *shp, smbios_port_ext_t *epp,
+ uint16_t *bdf)
+{
+ int devt;
+ id_t dev_id;
+ uint8_t bus, dev_funct;
+
+ char *f = "bay_bdf";
+
+ /*
+ * Depending on device type, BDF comes from either slot (type-9) or
+ * on-board (type-41) SMBIOS structure.
+ */
+ devt = epp->smbporte_dtype;
+ dev_id = epp->smbporte_devhdl;
+
+ if (devt == SMB_TYPE_SLOT) {
+ smbios_slot_t slot;
+ (void) smbios_info_slot(shp, dev_id, &slot);
+ bus = slot.smbl_bus;
+ dev_funct = slot.smbl_df;
+ } else if (devt == SMB_TYPE_OBDEVEXT) {
+ smbios_obdev_ext_t ob;
+ (void) smbios_info_obdevs_ext(shp, dev_id, &ob);
+ bus = ob.smboe_bus;
+ dev_funct = ob.smboe_df;
+ } else {
+ topo_mod_dprintf(mod, "%s: unknown device type: %d\n",
+ f, devt);
+ return (-1);
+ }
+ topo_mod_dprintf(mod, "%s: %s: bus(0x%02x) dev/func(0x%02x)\n", f,
+ devt == SMB_TYPE_SLOT ? "slot" : "ob dev", bus, dev_funct);
+
+ *bdf = BDF(bus, dev_funct);
+
+ return (0);
+}
+
+/*
+ * Decorate topo node with pgroups.
+ */
+int
+bay_pgroups(topo_mod_t *mod, tnode_t *tnp, di_node_t *dnp, di_node_t *sibp,
+ char *minor_name)
+{
+ int rv, err;
+ char *ap_path, *oc_path;
+
+ char *f = "bay_pgoups";
+
+ /*
+ * Create "io" pgroup and attachment point path.
+ */
+ rv = topo_pgroup_create(tnp, &io_pgroup, &err);
+ if (rv != 0) {
+ topo_mod_dprintf(mod,
+ "%s: failed to create \"io\" pgroup: %s\n",
+ f, topo_strerror(err));
+ (void) topo_mod_seterrno(mod, err);
+ return (err);
+ }
+
+ ap_path = topo_mod_alloc(mod, MAXPATHLEN);
+ if (ap_path == NULL) {
+ topo_mod_dprintf(mod, "%s: ap_path alloc failed\n");
+ return (topo_mod_seterrno(mod, EMOD_NOMEM));
+ }
+ (void) snprintf(ap_path, MAXPATHLEN, "%s%s:%s", DEVICES,
+ di_devfs_path(*dnp), minor_name);
+ topo_mod_dprintf(mod, "%s: ap_path(%s)\n", f, ap_path);
+
+ /* add ap-path */
+ rv = topo_prop_set_string(tnp, TOPO_PGROUP_IO, TOPO_IO_AP_PATH,
+ TOPO_PROP_IMMUTABLE, ap_path, &err);
+ if (rv != 0) {
+ topo_mod_dprintf(mod, "%s: failed to set ap-path: %s\n",
+ f, topo_strerror(err));
+ topo_mod_free(mod, ap_path, MAXPATHLEN);
+ (void) topo_mod_seterrno(mod, err);
+ return (err);
+ }
+ topo_mod_free(mod, ap_path, MAXPATHLEN);
+
+ /*
+ * Create "binding" pgroup and occupant path.
+ */
+ rv = topo_pgroup_create(tnp, &binding_pgroup, &err);
+ if (rv != 0) {
+ topo_mod_dprintf(mod,
+ "%s: failed to create \"io\" pgroup: %s\n",
+ f, topo_strerror(err));
+ (void) topo_mod_seterrno(mod, err);
+ return (err);
+ }
+
+ oc_path = di_devfs_path(*sibp);
+ if (oc_path == NULL) {
+ topo_mod_dprintf(mod, "%s: no occupant path\n", f);
+ return (-1);
+ }
+ topo_mod_dprintf(mod, "%s: oc_path(%s)\n", f, oc_path);
+
+ /* add ocupant-path */
+ rv = topo_prop_set_string(tnp, TOPO_PGROUP_BINDING,
+ TOPO_BINDING_OCCUPANT, TOPO_PROP_IMMUTABLE, oc_path,
+ &err);
+ if (rv != 0) {
+ topo_mod_dprintf(mod, "%s: failed to set ap-path: %s\n",
+ f, topo_strerror(err));
+ di_devfs_path_free(oc_path);
+ (void) topo_mod_seterrno(mod, err);
+ return (err);
+ }
+ di_devfs_path_free(oc_path);
+
+ return (0);
+}
+
+int
+bay_update_tnode(topo_mod_t *mod, tnode_t *tnodep, uint16_t bdf, int phy)
+{
+ int rv;
+ int minor_cnt = 0;
+ char *minor_name = NULL;
+ di_node_t devtree, dnode, sib;
+ di_minor_t minor = DI_MINOR_NIL;
+
+ char *f = "bay_update_tnode";
+
+ /*
+ * Find HBA device node from BDF.
+ */
+ devtree = topo_mod_devinfo(mod);
+ if (devtree == DI_NODE_NIL) {
+ topo_mod_dprintf(mod, "%s: failed to get dev tree\n", f);
+ return (-1);
+ }
+ for (dnode = di_drv_first_node(HBA_DRV_NAME, devtree);
+ dnode != DI_NODE_NIL;
+ dnode = di_drv_next_node(dnode)) {
+ if (bdf == x86pi_bdf(mod, dnode)) {
+ /*
+ * Match child node from PHY.
+ */
+ sib = di_child_node(dnode);
+ while (sib != DI_NODE_NIL) {
+ if (phy == x86pi_phy(mod, sib))
+ break;
+ sib = di_sibling_node(sib);
+ }
+ break;
+ }
+ }
+ if (dnode == DI_NODE_NIL) {
+ topo_mod_dprintf(mod, "%s: no HBA di_node\n", f);
+ return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
+ }
+
+ /*
+ * HBA attachment point minor node name.
+ */
+ while ((minor = di_minor_next(dnode, minor)) != DI_MINOR_NIL) {
+ if (strncmp(DDI_NT_SATA_ATTACHMENT_POINT,
+ di_minor_nodetype(minor),
+ strlen(DDI_NT_SATA_ATTACHMENT_POINT)) == 0) {
+ if (phy == minor_cnt++) {
+ minor_name = di_minor_name(minor);
+ topo_mod_dprintf(mod,
+ "%s: phy(%d) minor name(%s)\n",
+ f, phy, minor_name);
+ break;
+ }
+ }
+ }
+
+ rv = bay_pgroups(mod, tnodep, &dnode, &sib, minor_name);
+ if (rv != 0) {
+ topo_mod_dprintf(mod, "%s: failed to add pgroups\n", f);
+ return (-1);
+ }
+
+
+ return (0);
+}
+
+/*
+ * x86pi_gen_bay:
+ * create "bay" node
+ * call "disk" enum passing in "bay" node
+ */
+int
+x86pi_gen_bay(topo_mod_t *mod, tnode_t *t_parent, smbios_hdl_t *shp,
+ smbios_port_ext_t *eport, int instance)
+{
+ int rv;
+ int min = 0, max = 0;
+ id_t port_id;
+ uint16_t bdf;
+ smbios_port_t smb_port;
+ x86pi_hcfmri_t hcfmri = {0};
+ tnode_t *tn_bay;
+
+ char *f = "x86pi_gen_disk";
+
+ /*
+ * Label comes from the port (type-8) SMBIOS structure.
+ */
+ port_id = eport->smbporte_port;
+
+ rv = smbios_info_port(shp, port_id, &smb_port);
+ if (rv != 0) {
+ topo_mod_dprintf(mod,
+ "%s: failed to get port %d SMBIOS struct\n",
+ f, port_id);
+ return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
+ }
+
+ /*
+ * Fill in hcfmri info.
+ */
+ hcfmri.hc_name = BAY;
+ hcfmri.instance = instance;
+ hcfmri.location = x86pi_cleanup_smbios_str(mod, smb_port.smbo_eref, 0);
+
+ /*
+ * Create "bay" node.
+ */
+ rv = x86pi_enum_generic(mod, &hcfmri, t_parent, t_parent, &tn_bay, 0);
+ if (rv != 0) {
+ topo_mod_dprintf(mod,
+ "%s: failed to create %s topo node: %d\n",
+ f, BAY, instance);
+ return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
+ }
+
+ /* free up location string */
+ if (hcfmri.location != NULL) {
+ topo_mod_strfree(mod, (char *)hcfmri.location);
+ }
+
+ /*
+ * Determine the bay BDF.
+ */
+ rv = bay_bdf(mod, shp, eport, &bdf);
+ if (rv != 0) {
+ topo_mod_dprintf(mod, "%s: failed to get BDF\n", f);
+ return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
+ }
+ topo_mod_dprintf(mod, "%s: BDF(0x%04x)\n", f, bdf);
+
+ /*
+ * Decorate bay topo node.
+ */
+ rv = bay_update_tnode(mod, tn_bay, bdf, eport->smbporte_phy);
+ if (rv != 0) {
+ topo_mod_dprintf(mod, "%s: failed to decorate bay node\n", f);
+ return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
+ }
+
+ /*
+ * Call disk enum passing in decorated bay topo node.
+ */
+ if (topo_mod_load(mod, DISK, TOPO_VERSION) == NULL) {
+ topo_mod_dprintf(mod, "%s: Failed to load %s module: %s\n",
+ f, DISK, topo_strerror(topo_mod_errno(mod)));
+ return (topo_mod_errno(mod));
+ }
+
+ rv = topo_node_range_create(mod, tn_bay, DISK, min, max);
+ if (rv != 0) {
+ topo_mod_dprintf(mod, "%s: failed to create range: %s\n", f,
+ topo_strerror(topo_mod_errno(mod)));
+ return (topo_mod_errno(mod));
+ }
+
+ rv = topo_mod_enumerate(mod, tn_bay, DISK, DISK, min, max, NULL);
+ if (rv != 0) {
+ topo_mod_dprintf(mod, "%s: %s enumeration failed: %s\n", f,
+ DISK, topo_strerror(topo_mod_errno(mod)));
+ return (topo_mod_errno(mod));
+ }
+
+ topo_mod_dprintf(mod, "%s: done.\n", f);
+
+ return (0);
+}
diff --git a/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_hostbridge.c b/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_hostbridge.c
index c3b5857634..4c27f2dcfd 100644
--- a/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_hostbridge.c
+++ b/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_hostbridge.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -99,20 +99,6 @@ x86pi_hbr_enum_fini(topo_mod_t *mod)
}
}
-static uint16_t
-x86pi_bdf(topo_mod_t *mod, di_node_t node)
-{
- int *val;
-
- if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "reg", &val) < 0) {
- topo_mod_dprintf(mod, "couldn't get \"reg\" prop: %s.\n",
- strerror(errno));
- return ((uint16_t)-1);
- }
-
- return (uint16_t)((*val & PCI_REG_BDFR_M) >> PCI_REG_FUNC_SHIFT);
-}
-
static int
pciex_process(topo_mod_t *mod, tnode_t *tn_hbr, di_node_t rcn,
topo_instance_t rci)
diff --git a/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_impl.h b/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_impl.h
index fa0cbf674f..491e286747 100644
--- a/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_impl.h
+++ b/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_impl.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -58,6 +58,8 @@ extern "C" {
* | "systemboard" | Type 2 | 0x0D - Board Type | 0x03,0x09,|
* | | | | 0x0B,0x0C |
* --------------------------------------------------------------------------
+ * | "bay" | Type 136 | |
+ * --------------------------------------------------------------------------
* | "hostbridge" | Type 138 | |
* --------------------------------------------------------------------------
* | "pciexrc" | Type 138 | |
@@ -172,6 +174,8 @@ int x86pi_gen_memarray(topo_mod_t *, tnode_t *, smbios_hdl_t *, int, int);
void x86pi_gen_memdev(topo_mod_t *, tnode_t *, smbios_hdl_t *, int, int, int);
int x86pi_gen_hbr(topo_mod_t *, tnode_t *, smbios_hdl_t *, int,
topo_instance_t, topo_instance_t *);
+int x86pi_gen_bay(topo_mod_t *, tnode_t *, smbios_hdl_t *, smbios_port_ext_t *,
+ int);
/* support routines */
int x86pi_enum_generic(topo_mod_t *, x86pi_hcfmri_t *, tnode_t *, tnode_t *,
@@ -179,6 +183,8 @@ int x86pi_enum_generic(topo_mod_t *, x86pi_hcfmri_t *, tnode_t *, tnode_t *,
tnode_t *x86pi_node_bind(topo_mod_t *, tnode_t *, x86pi_hcfmri_t *, nvlist_t *,
int);
void x86pi_hcfmri_info_fini(topo_mod_t *, x86pi_hcfmri_t *);
+uint16_t x86pi_bdf(topo_mod_t *, di_node_t);
+int x86pi_phy(topo_mod_t *, di_node_t);
/* get/set info */
char *x86pi_get_serverid(topo_mod_t *);
diff --git a/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_subr.c b/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_subr.c
index 3382592da3..9cb79e339b 100644
--- a/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_subr.c
+++ b/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_subr.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,6 +36,7 @@
#include <fm/topo_mod.h>
#include <fm/topo_hc.h>
#include <sys/devfm.h>
+#include <sys/pci.h>
#include <sys/systeminfo.h>
#include <sys/fm/protocol.h>
#include <sys/utsname.h>
@@ -651,3 +652,37 @@ x86pi_cleanup_smbios_str(topo_mod_t *mod, const char *begin, int str_type)
return (pp);
}
+
+/*
+ * Return Bus/Dev/Func from "reg" devinfo property.
+ */
+uint16_t
+x86pi_bdf(topo_mod_t *mod, di_node_t node)
+{
+ int *val;
+
+ if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "reg", &val) < 0) {
+ topo_mod_dprintf(mod, "couldn't get \"reg\" prop: %s.\n",
+ strerror(errno));
+ return ((uint16_t)-1);
+ }
+
+ return (uint16_t)((*val & PCI_REG_BDFR_M) >> PCI_REG_FUNC_SHIFT);
+}
+
+/*
+ * Return PHY from "sata-phy" devinfo proporty.
+ */
+int
+x86pi_phy(topo_mod_t *mod, di_node_t node)
+{
+ int *phy;
+
+ if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "sata-phy", &phy) < 0) {
+ topo_mod_dprintf(mod, "couldn't get \"sata-phy\" prop: %s.\n",
+ strerror(errno));
+ return (-1);
+ }
+
+ return (*phy);
+}
diff --git a/usr/src/lib/libsmbios/common/mapfile-vers b/usr/src/lib/libsmbios/common/mapfile-vers
index 0fc59e6210..f1223e1ffa 100644
--- a/usr/src/lib/libsmbios/common/mapfile-vers
+++ b/usr/src/lib/libsmbios/common/mapfile-vers
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -93,7 +93,9 @@ SUNWprivate_1.1 {
smbios_info_extmemdevice;
smbios_info_memdevmap;
smbios_info_obdevs;
+ smbios_info_obdevs_ext;
smbios_info_port;
+ smbios_info_extport;
smbios_info_processor;
smbios_info_extprocessor;
smbios_info_slot;
diff --git a/usr/src/uts/common/io/sata/impl/sata.c b/usr/src/uts/common/io/sata/impl/sata.c
index b51502bd51..e74e8cbb3c 100644
--- a/usr/src/uts/common/io/sata/impl/sata.c
+++ b/usr/src/uts/common/io/sata/impl/sata.c
@@ -10370,6 +10370,19 @@ sata_create_target_node(dev_info_t *dip, sata_hba_inst_t *sata_hba_inst,
goto fail;
}
+ if (sdinfo->satadrv_type == SATA_DTYPE_ATADISK) {
+ /*
+ * Add "sata-phy" property
+ */
+ if (ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "sata-phy",
+ (int)sata_addr->cport) != DDI_PROP_SUCCESS) {
+ SATA_LOG_D((sata_hba_inst, CE_WARN,
+ "sata_create_target_node: failed to create "
+ "\"sata-phy\" property: port %d",
+ sata_addr->cport));
+ }
+ }
+
/*
* Now, try to attach the driver. If probing of the device fails,
diff --git a/usr/src/uts/common/sys/smbios.h b/usr/src/uts/common/sys/smbios.h
index a21dceb5e3..c9f9570e8e 100644
--- a/usr/src/uts/common/sys/smbios.h
+++ b/usr/src/uts/common/sys/smbios.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -122,11 +122,13 @@ typedef struct smbios_entry {
#define SMB_TYPE_MEMCHAN 37 /* memory channel */
#define SMB_TYPE_IPMIDEV 38 /* IPMI device information */
#define SMB_TYPE_POWERSUP 39 /* system power supply */
+#define SMB_TYPE_OBDEVEXT 41 /* on-board device extended info */
#define SMB_TYPE_INACTIVE 126 /* inactive table entry */
#define SMB_TYPE_EOT 127 /* end of table */
#define SMB_TYPE_OEM_LO 128 /* start of OEM-specific type range */
#define SUN_OEM_EXT_PROCESSOR 132 /* processor extended info */
+#define SUN_OEM_EXT_PORT 136 /* port exteded info */
#define SUN_OEM_PCIEXRC 138 /* PCIE RootComplex/RootPort info */
#define SUN_OEM_EXT_MEMARRAY 144 /* phys memory array extended info */
#define SUN_OEM_EXT_MEMDEVICE 145 /* memory device extended info */
@@ -713,6 +715,9 @@ typedef struct smbios_slot {
uint16_t smbl_id; /* slot ID */
uint8_t smbl_ch1; /* slot characteristics 1 */
uint8_t smbl_ch2; /* slot characteristics 2 */
+ uint16_t smbl_sg; /* segment group number */
+ uint8_t smbl_bus; /* bus number */
+ uint8_t smbl_df; /* device/function number */
} smbios_slot_t;
#define SMB_SLT_OTHER 0x01 /* other */
@@ -1079,6 +1084,20 @@ typedef struct smbios_ipmi {
#define SMB_IPMI_F_INTREDGE 0x08 /* intr is edge triggered (else lvl) */
/*
+ * SMBIOS Onboard Devices Extended Information. See DSP0134 Section 3.3.42
+ * for more information.
+ */
+typedef struct smbios_obdev_ext {
+ const char *smboe_name; /* reference designation */
+ uint8_t smboe_dtype; /* device type */
+ uint8_t smboe_dti; /* device type instance */
+ uint16_t smboe_sg; /* segment group number */
+ uint8_t smboe_bus; /* bus number */
+ uint8_t smboe_df; /* device/function number */
+} smbios_obdev_ext_t;
+
+
+/*
* SMBIOS OEM-specific (Type 132) Processor Extended Information.
*/
typedef struct smbios_processor_ext {
@@ -1089,6 +1108,17 @@ typedef struct smbios_processor_ext {
} smbios_processor_ext_t;
/*
+ * SMBIOS OEM-specific (Type 136) Port Extended Information.
+ */
+typedef struct smbios_port_ext {
+ uint16_t smbporte_chassis; /* chassis handle */
+ uint16_t smbporte_port; /* port connector handle */
+ uint8_t smbporte_dtype; /* device type */
+ uint16_t smbporte_devhdl; /* device handle */
+ uint8_t smbporte_phy; /* PHY number */
+} smbios_port_ext_t;
+
+/*
* SMBIOS OEM-specific (Type 138) PCI-Express RC/RP Information.
*/
typedef struct smbios_pciexrc {
@@ -1183,8 +1213,10 @@ extern int smbios_info_extprocessor(smbios_hdl_t *, id_t,
smbios_processor_ext_t *);
extern int smbios_info_cache(smbios_hdl_t *, id_t, smbios_cache_t *);
extern int smbios_info_port(smbios_hdl_t *, id_t, smbios_port_t *);
+extern int smbios_info_extport(smbios_hdl_t *, id_t, smbios_port_ext_t *);
extern int smbios_info_slot(smbios_hdl_t *, id_t, smbios_slot_t *);
extern int smbios_info_obdevs(smbios_hdl_t *, id_t, int, smbios_obdev_t *);
+extern int smbios_info_obdevs_ext(smbios_hdl_t *, id_t, smbios_obdev_ext_t *);
extern int smbios_info_strtab(smbios_hdl_t *, id_t, int, const char *[]);
extern id_t smbios_info_lang(smbios_hdl_t *, smbios_lang_t *);
extern id_t smbios_info_eventlog(smbios_hdl_t *, smbios_evlog_t *);
diff --git a/usr/src/uts/common/sys/smbios_impl.h b/usr/src/uts/common/sys/smbios_impl.h
index b1ac86b1b5..786c7f641a 100644
--- a/usr/src/uts/common/sys/smbios_impl.h
+++ b/usr/src/uts/common/sys/smbios_impl.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -185,6 +185,9 @@ typedef struct smb_slot {
uint16_t smbsl_id; /* slot ID */
uint8_t smbsl_ch1; /* slot characteristics 1 */
uint8_t smbsl_ch2; /* slot characteristics 2 */
+ uint16_t smbsl_sg; /* segment group number */
+ uint8_t smbsl_bus; /* bus number */
+ uint8_t smbsl_df; /* device/function number */
} smb_slot_t;
typedef struct smb_obdev {
@@ -357,6 +360,16 @@ typedef struct smb_powersup {
uint16_t smbpsup_iprobe; /* current probe handle */
} smb_powersup_t;
+typedef struct smb_obdev_ext {
+ smb_header_t smbobe_hdr; /* structure header */
+ uint8_t smbobe_name; /* reference designation */
+ uint8_t smbobe_dtype; /* device type */
+ uint8_t smbobe_dti; /* device type instance */
+ uint16_t smbobe_sg; /* segment group number */
+ uint8_t smbobe_bus; /* bus number */
+ uint8_t smbobe_df; /* device/function number */
+} smb_obdev_ext_t;
+
typedef struct smb_processor_ext {
smb_header_t smbpre_hdr; /* structure header */
uint16_t smbpre_processor; /* processor handle */
@@ -365,6 +378,15 @@ typedef struct smb_processor_ext {
uint16_t smbpre_apicid[1]; /* strand initial apic id */
} smb_processor_ext_t;
+typedef struct smb_port_ext {
+ smb_header_t smbpoe_hdr; /* structure header */
+ uint16_t smbpoe_chassis; /* chassis handle */
+ uint16_t smbpoe_port; /* port connector handle */
+ uint8_t smbpoe_dtype; /* device type */
+ uint16_t smbpoe_devhdl; /* device handle */
+ uint8_t smbpoe_phy; /* PHY number */
+} smb_port_ext_t;
+
typedef struct smb_pciexrc {
smb_header_t smbpciexrc_hdr; /* structure header */
uint16_t smbpciexrc_bboard; /* base board handle */