summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorLuping Quan <Luping.Quan@Oracle.COM>2010-08-07 02:00:01 -0400
committerLuping Quan <Luping.Quan@Oracle.COM>2010-08-07 02:00:01 -0400
commit63d763c84bef3a708cb75b6de1f5f809681e788c (patch)
tree14015eb78278f6c311756ff82226246ca12771af /usr/src
parent982b0713931a84acf37ebcf79dccb82dffb00588 (diff)
downloadillumos-joyent-63d763c84bef3a708cb75b6de1f5f809681e788c.tar.gz
6970650 Fix fdd-msg to send processor specific FMA capability to ILOM
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/fm/modules/common/fdd-msg/Makefile10
-rw-r--r--usr/src/cmd/fm/modules/common/fdd-msg/fdd-msg.conf15
-rw-r--r--usr/src/cmd/fm/modules/common/fdd-msg/fdd_msg.c231
3 files changed, 193 insertions, 63 deletions
diff --git a/usr/src/cmd/fm/modules/common/fdd-msg/Makefile b/usr/src/cmd/fm/modules/common/fdd-msg/Makefile
index da07c3ff28..be3a173e7f 100644
--- a/usr/src/cmd/fm/modules/common/fdd-msg/Makefile
+++ b/usr/src/cmd/fm/modules/common/fdd-msg/Makefile
@@ -19,8 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
#
MODULE = fdd-msg
@@ -29,4 +28,9 @@ SRCS = fdd_msg.c
include ../../Makefile.plugin
-LDLIBS += -lipmi
+LDLIBS_sparc = -lipmi
+LDLIBS_i386 = -L$(ROOT)/usr/lib/fm -lipmi -lumem -lfmd_agent
+LDFLAGS_sparc =
+LDFLAGS_i386 = -R/usr/lib/fm
+LDLIBS += $(LDLIBS_$(MACH))
+LDFLAGS += $(LDFLAGS_$(MACH))
diff --git a/usr/src/cmd/fm/modules/common/fdd-msg/fdd-msg.conf b/usr/src/cmd/fm/modules/common/fdd-msg/fdd-msg.conf
index 673f715efe..d4c974e871 100644
--- a/usr/src/cmd/fm/modules/common/fdd-msg/fdd-msg.conf
+++ b/usr/src/cmd/fm/modules/common/fdd-msg/fdd-msg.conf
@@ -19,6 +19,15 @@
# CDDL HEADER END
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
+# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+setprop default_fma_cap 0x3
+
+# vendor=GenuineIntel, family=6, model=26
+setprop NHMEP_fma_cap 0x3
+# vendor=GenuineIntel, family=6, model=46
+setprop NHMEX_fma_cap 0x2
+# vendor=GenuineIntel, family=6, model=44
+setprop WSMEP_fma_cap 0x3
+# vendor=GenuineIntel, family=6, model=47
+setprop INTLN_fma_cap 0x2
diff --git a/usr/src/cmd/fm/modules/common/fdd-msg/fdd_msg.c b/usr/src/cmd/fm/modules/common/fdd-msg/fdd_msg.c
index 3d643deb52..7137297c0b 100644
--- a/usr/src/cmd/fm/modules/common/fdd-msg/fdd_msg.c
+++ b/usr/src/cmd/fm/modules/common/fdd-msg/fdd_msg.c
@@ -20,22 +20,25 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * fdd messenger
+ * FMA capability messenger
*
- * This module sends fdd running on service processor a message which
- * indicates the Solaris host FMA capability when fmd is started. The
- * message is sent via the BMC driver (KCS interface) to the IPMI stack
- * of ILOM using the IPMI Sun OEM core tunnel command. The sub-command
- * is CORE_TUNNEL_SUBCMD_HOSTCAP. The IPMI stack posts an host FMA
- * capability event to the event manager upon receiving this message.
- * fdd subscribes to the event manager for this event. Upon receving
- * this event, fdd will adjust its configuration.
+ * fdd-msg module is called once when fmd starts up. It does the following
+ * based on different scenarios
*
+ * 1. If it's on a x86 platform, fdd-msg module sends fdd running on service
+ * processor a message (ILOM) which indicates the Solaris host FMA capability.
+ * The message is sent via the BMC driver (KCS interface) to the IPMI stack
+ * of ILOM using the IPMI Sun OEM core tunnel command. The sub-command is
+ * CORE_TUNNEL_SUBCMD_HOSTCAP. The IPMI stack posts an host FMA capability
+ * event to the event manager upon receiving this message. fdd subscribes to
+ * the event manager for this event. Upon receving this event, fdd will adjust
+ * its configuration.
+ *
+ * 2. If it's on a Sparc platform, fdd-msg module just exit for now.
*/
#include <errno.h>
@@ -43,13 +46,35 @@
#include <strings.h>
#include <sys/systeminfo.h>
#include <libipmi.h>
+#include <sys/devfm.h>
#include <fm/fmd_api.h>
+#if defined(__x86)
+#include <sys/x86_archext.h>
+#include <fm/fmd_agent.h>
+#include <libnvpair.h>
+#endif
#define CMD_SUNOEM_CORE_TUNNEL 0x44
#define CORE_TUNNEL_SUBCMD_HOSTFMACAP 2
#define OEM_DATA_LENGTH 3
#define VERSION 0x10
-#define HOST_CAPABILITY 2
+
+#if defined(__x86)
+typedef struct cpu_tbl {
+ char vendor[X86_VENDOR_STRLEN];
+ int32_t family;
+ int32_t model;
+ char *propname;
+} cpu_tbl_t;
+
+static cpu_tbl_t fma_cap_list[] = {
+ {"GenuineIntel", 6, 26, "NHMEP_fma_cap"},
+ {"GenuineIntel", 6, 46, "NHMEX_fma_cap"},
+ {"GenuineIntel", 6, 44, "WSMEP_fma_cap"},
+ {"GenuineIntel", 6, 47, "INTLN_fma_cap"},
+ {NULL, 0, 0, NULL}
+};
+#endif
static int
check_sunoem(ipmi_handle_t *ipmi_hdl)
@@ -65,19 +90,127 @@ check_sunoem(ipmi_handle_t *ipmi_hdl)
return (0);
}
-/*ARGSUSED*/
+#if defined(__x86)
+static int32_t
+fma_cap_cpu_info(cpu_tbl_t *ci)
+{
+ nvlist_t **cpus, *nvl;
+ uint_t ncpu, i;
+ fmd_agent_hdl_t *hdl;
+ char *ven;
+ int32_t family, model;
+
+ if ((hdl = fmd_agent_open(FMD_AGENT_VERSION)) == NULL)
+ return (-1);
+ if (fmd_agent_physcpu_info(hdl, &cpus, &ncpu) != 0) {
+ fmd_agent_close(hdl);
+ return (-1);
+ }
+ fmd_agent_close(hdl);
+
+ if (cpus == NULL)
+ return (-1);
+
+ /*
+ * There is no mixed CPU type on x86 systems, it's ok to
+ * just pick the first one
+ */
+ nvl = cpus[0];
+ if (nvlist_lookup_string(nvl, FM_PHYSCPU_INFO_VENDOR_ID, &ven) != 0 ||
+ nvlist_lookup_int32(nvl, FM_PHYSCPU_INFO_FAMILY, &family) != 0 ||
+ nvlist_lookup_int32(nvl, FM_PHYSCPU_INFO_MODEL, &model) != 0) {
+ for (i = 0; i < ncpu; i++)
+ nvlist_free(cpus[i]);
+ umem_free(cpus, sizeof (nvlist_t *) * ncpu);
+ return (-1);
+ }
+
+ (void) snprintf(ci->vendor, X86_VENDOR_STRLEN, "%s", ven);
+ ci->family = family;
+ ci->model = model;
+
+ for (i = 0; i < ncpu; i++)
+ nvlist_free(cpus[i]);
+ umem_free(cpus, sizeof (nvlist_t *) * ncpu);
+ return (0);
+}
+#endif
+
+static uint32_t
+get_cap_conf(fmd_hdl_t *hdl)
+{
+ uint32_t fma_cap;
+#if defined(__x86)
+ int found = 0;
+ cpu_tbl_t *cl, ci;
+
+ if (fma_cap_cpu_info(&ci) == 0) {
+ fmd_hdl_debug(hdl, "Got CPU info: vendor=%s, family=%d, "
+ "model=%d\n", ci.vendor, ci.family, ci.model);
+ for (cl = fma_cap_list; cl->propname != NULL; cl++) {
+ if (strncmp(ci.vendor, cl->vendor,
+ X86_VENDOR_STRLEN) == 0 &&
+ ci.family == cl->family &&
+ ci.model == cl->model) {
+ found++;
+ break;
+ }
+ }
+ } else {
+ fmd_hdl_debug(hdl, "Failed to get CPU info");
+ }
+
+ if (found) {
+ fma_cap = fmd_prop_get_int32(hdl, cl->propname);
+ fmd_hdl_debug(hdl, "Found property, FMA capability=0x%x",
+ fma_cap);
+ } else {
+#endif
+ fma_cap = fmd_prop_get_int32(hdl, "default_fma_cap");
+ fmd_hdl_debug(hdl, "Didn't find FMA capability property, "
+ "use default=0x%x", fma_cap);
+#if defined(__x86)
+ }
+#endif
+
+ return (fma_cap);
+}
+
static void
-send_fma_cap(fmd_hdl_t *hdl, id_t id, void *data)
+send_fma_cap_to_ilom(fmd_hdl_t *hdl, uint32_t fma_cap)
{
+ int error;
+ char *msg;
ipmi_handle_t *ipmi_hdl;
ipmi_cmd_t cmd;
uint8_t oem_data[OEM_DATA_LENGTH];
- ipmi_hdl = fmd_hdl_getspecific(hdl);
+ if ((ipmi_hdl = ipmi_open(&error, &msg, IPMI_TRANSPORT_BMC, NULL))
+ == NULL) {
+ /*
+ * If /dev/bmc doesn't exist on the system, then return
+ * without doing anything.
+ */
+ if (error != EIPMI_BMC_OPEN_FAILED)
+ fmd_hdl_abort(hdl, "Failed to initialize IPMI "
+ "connection: %s\n", msg);
+ fmd_hdl_debug(hdl, "Failed: no IPMI connection present");
+ return;
+ }
+
+ /*
+ * Check if it's Sun ILOM
+ */
+ if (check_sunoem(ipmi_hdl) != 0) {
+ fmd_hdl_debug(hdl, "Service Processor does not run "
+ "Sun ILOM");
+ ipmi_close(ipmi_hdl);
+ return;
+ }
oem_data[0] = CORE_TUNNEL_SUBCMD_HOSTFMACAP;
oem_data[1] = VERSION;
- oem_data[2] = HOST_CAPABILITY;
+ oem_data[2] = fma_cap;
cmd.ic_netfn = IPMI_NETFN_OEM;
cmd.ic_lun = 0;
@@ -87,17 +220,27 @@ send_fma_cap(fmd_hdl_t *hdl, id_t id, void *data)
if (ipmi_send(ipmi_hdl, &cmd) == NULL) {
fmd_hdl_debug(hdl, "Failed to send Solaris FMA "
- "capability to fdd: %s", ipmi_errmsg(ipmi_hdl));
+ "capability to ilom: %s", ipmi_errmsg(ipmi_hdl));
}
ipmi_close(ipmi_hdl);
- fmd_hdl_setspecific(hdl, NULL);
+}
+
+/*ARGSUSED*/
+static void
+fma_cap_init(fmd_hdl_t *hdl, id_t id, void *data)
+{
+ uint32_t fma_cap;
+
+ fma_cap = get_cap_conf(hdl);
+ send_fma_cap_to_ilom(hdl, fma_cap);
+
fmd_hdl_unregister(hdl);
}
static const fmd_hdl_ops_t fmd_ops = {
NULL, /* fmdo_recv */
- send_fma_cap, /* fmdo_timeout */
+ fma_cap_init, /* fmdo_timeout */
NULL, /* fmdo_close */
NULL, /* fmdo_stats */
NULL, /* fmdo_gc */
@@ -107,22 +250,28 @@ static const fmd_hdl_ops_t fmd_ops = {
static const fmd_prop_t fmd_props[] = {
{ "interval", FMD_TYPE_TIME, "1s" },
+ { "default_fma_cap", FMD_TYPE_UINT32, "0x3" },
+ { "NHMEP_fma_cap", FMD_TYPE_UINT32, "0x3" },
+ { "NHMEX_fma_cap", FMD_TYPE_UINT32, "0x2" },
+ { "WSMEP_fma_cap", FMD_TYPE_UINT32, "0x3" },
+ { "INTLN_fma_cap", FMD_TYPE_UINT32, "0x2" },
{ NULL, 0, NULL }
};
static const fmd_hdl_info_t fmd_info = {
- "fdd Messenger", "1.0", &fmd_ops, fmd_props
+ "FMA Capability Messenger", "1.1", &fmd_ops, fmd_props
};
void
_fmd_init(fmd_hdl_t *hdl)
{
- ipmi_handle_t *ipmi_hdl;
- int error;
- char *msg;
char isa[8];
- /* For now the module only sends message to ILOM on i386 platforms */
+ /*
+ * For now the module only sends message to ILOM on i386 platforms
+ * till CR 6933053 is fixed. Module unregister may cause etm module
+ * core dump due to 6933053.
+ */
if ((sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)) == -1) ||
(strncmp(isa, "i386", 4) != 0))
return;
@@ -130,46 +279,14 @@ _fmd_init(fmd_hdl_t *hdl)
if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0)
return;
- if ((ipmi_hdl = ipmi_open(&error, &msg, IPMI_TRANSPORT_BMC, NULL))
- == NULL) {
- /*
- * If /dev/bmc doesn't exist on the system, then unload the
- * module without doing anything.
- */
- if (error != EIPMI_BMC_OPEN_FAILED)
- fmd_hdl_abort(hdl, "Failed to initialize IPMI "
- "connection: %s\n", msg);
- fmd_hdl_debug(hdl, "Failed to load: no IPMI connection "
- "present");
- fmd_hdl_unregister(hdl);
- return;
- }
-
- /*
- * Check if it's Sun ILOM
- */
- if (check_sunoem(ipmi_hdl) != 0) {
- fmd_hdl_debug(hdl, "Service Processor does not run "
- "Sun ILOM");
- ipmi_close(ipmi_hdl);
- fmd_hdl_unregister(hdl);
- return;
- }
-
- fmd_hdl_setspecific(hdl, ipmi_hdl);
-
/*
* Setup the timer.
*/
(void) fmd_timer_install(hdl, NULL, NULL, 2000000000ULL);
}
+/*ARGSUSED*/
void
_fmd_fini(fmd_hdl_t *hdl)
{
- ipmi_handle_t *ipmi_hdl = fmd_hdl_getspecific(hdl);
-
- if (ipmi_hdl) {
- ipmi_close(ipmi_hdl);
- }
}