summaryrefslogtreecommitdiff
path: root/usr/src/lib/libipmi
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libipmi')
-rw-r--r--usr/src/lib/libipmi/common/ipmi_fru.c38
-rw-r--r--usr/src/lib/libipmi/common/ipmi_misc.c34
-rw-r--r--usr/src/lib/libipmi/common/libipmi.h56
-rw-r--r--usr/src/lib/libipmi/common/mapfile-vers5
4 files changed, 125 insertions, 8 deletions
diff --git a/usr/src/lib/libipmi/common/ipmi_fru.c b/usr/src/lib/libipmi/common/ipmi_fru.c
index d652c23cd4..b429f91934 100644
--- a/usr/src/lib/libipmi/common/ipmi_fru.c
+++ b/usr/src/lib/libipmi/common/ipmi_fru.c
@@ -22,9 +22,9 @@
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
+/*
+ * Copyright (c) 2017, Joyent, Inc.
+ */
#include <libipmi.h>
#include <string.h>
@@ -36,6 +36,13 @@
*/
#define BITX(u, h, l) (((u) >> (l)) & ((1LU << ((h) - (l) + 1LU)) - 1LU))
+/*
+ * The default and minimum size in bytes that will be used when reading
+ * the FRU inventory area.
+ */
+#define DEF_CHUNK_SZ 128
+#define MIN_CHUNK_SZ 16
+
typedef struct ipmi_fru_read
{
uint8_t ifr_devid;
@@ -52,7 +59,8 @@ int
ipmi_fru_read(ipmi_handle_t *ihp, ipmi_sdr_fru_locator_t *fru_loc, char **buf)
{
ipmi_cmd_t cmd, *resp;
- uint8_t count, devid;
+ int ierrno;
+ uint8_t count, devid, chunksz;
uint16_t sz, offset = 0;
ipmi_fru_read_t cmd_data_in;
char *tmp;
@@ -82,14 +90,15 @@ ipmi_fru_read(ipmi_handle_t *ihp, ipmi_sdr_fru_locator_t *fru_loc, char **buf)
return (-1);
}
+ chunksz = DEF_CHUNK_SZ;
while (offset < sz) {
cmd_data_in.ifr_devid = devid;
cmd_data_in.ifr_offset_lsb = BITX(offset, 7, 0);
cmd_data_in.ifr_offset_msb = BITX(offset, 15, 8);
- if ((sz - offset) < 128)
+ if ((sz - offset) < chunksz)
cmd_data_in.ifr_count = sz - offset;
else
- cmd_data_in.ifr_count = 128;
+ cmd_data_in.ifr_count = chunksz;
cmd.ic_netfn = IPMI_NETFN_STORAGE;
cmd.ic_cmd = IPMI_CMD_READ_FRU_DATA;
@@ -97,7 +106,24 @@ ipmi_fru_read(ipmi_handle_t *ihp, ipmi_sdr_fru_locator_t *fru_loc, char **buf)
cmd.ic_dlen = sizeof (ipmi_fru_read_t);
cmd.ic_lun = 0;
+ /*
+ * The FRU area must be read in chunks as its total size will
+ * be larger that what would fit in a single message. The
+ * maximum size of a message can vary between platforms so
+ * if while attempting to read a chunk we receive an error code
+ * indicating that the requested chunk size is invalid, we will
+ * perform a reverse exponential backoff of the chunk size until
+ * either the read succeeds or we hit bottom, at which point
+ * we'll fail the operation.
+ */
if ((resp = ipmi_send(ihp, &cmd)) == NULL) {
+ ierrno = ipmi_errno(ihp);
+ if (chunksz > MIN_CHUNK_SZ &&
+ (ierrno == EIPMI_DATA_LENGTH_EXCEEDED ||
+ ierrno == EIPMI_INVALID_REQUEST)) {
+ chunksz = chunksz >> 1;
+ continue;
+ }
free(tmp);
return (-1);
}
diff --git a/usr/src/lib/libipmi/common/ipmi_misc.c b/usr/src/lib/libipmi/common/ipmi_misc.c
index f83e9e1802..221093e630 100644
--- a/usr/src/lib/libipmi/common/ipmi_misc.c
+++ b/usr/src/lib/libipmi/common/ipmi_misc.c
@@ -20,8 +20,8 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, Joyent, Inc.
*/
-
#include <libipmi.h>
#include <stdio.h>
#include <string.h>
@@ -222,3 +222,35 @@ ipmi_chassis_identify(ipmi_handle_t *ihp, boolean_t enable)
return (0);
}
+
+/*
+ * calller is responsible for free'ing returned structure
+ */
+ipmi_chassis_status_t *
+ipmi_chassis_status(ipmi_handle_t *ihp)
+{
+ ipmi_cmd_t cmd, *rsp;
+ ipmi_chassis_status_t *chs;
+
+ cmd.ic_netfn = IPMI_NETFN_CHASSIS;
+ cmd.ic_lun = 0;
+ cmd.ic_cmd = IPMI_CMD_GET_CHASSIS_STATUS;
+ cmd.ic_data = NULL;
+ cmd.ic_dlen = 0;
+
+ if ((rsp = ipmi_send(ihp, &cmd)) == NULL)
+ return (NULL);
+
+ if (rsp->ic_dlen < sizeof (ipmi_chassis_status_t)) {
+ (void) ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL);
+ return (NULL);
+ }
+
+ if ((chs = ipmi_alloc(ihp, sizeof (ipmi_chassis_status_t))) == NULL) {
+ /* ipmi errno set */
+ return (NULL);
+ }
+
+ (void) memcpy(chs, rsp->ic_data, sizeof (ipmi_chassis_status_t));
+ return (chs);
+}
diff --git a/usr/src/lib/libipmi/common/libipmi.h b/usr/src/lib/libipmi/common/libipmi.h
index af8a1f6351..8552585405 100644
--- a/usr/src/lib/libipmi/common/libipmi.h
+++ b/usr/src/lib/libipmi/common/libipmi.h
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2017, Joyent, Inc. All rights reserved.
*/
#ifndef _LIBIPMI_H
@@ -1849,6 +1849,60 @@ typedef struct ipmi_sunoem_fru {
int ipmi_sunoem_update_fru(ipmi_handle_t *, ipmi_sunoem_fru_t *);
+/*
+ * See section 28.2
+ */
+#define IPMI_CMD_GET_CHASSIS_STATUS 0x01
+
+/*
+ * flags for ichs_current_pwr_state field
+ */
+#define IPMI_CURR_PWR_STATE_ON 0x01
+#define IPMI_CURR_PWR_STATE_OVERLOAD 0x02
+#define IPMI_CURR_PWR_STATE_INTERLOCK 0x04
+#define IPMI_CURR_PWR_STATE_FAULT 0x08
+#define IPMI_CURR_PWR_STATE_CNTL_FAULT 0x10
+
+/*
+ * flags for ichs_last_pwr_state field
+ */
+#define IPMI_LAST_PWR_STATE_ACFAILED 0x01
+#define IPMI_LAST_PWR_STATE_OVERLOAD 0x02
+#define IPMI_LAST_PWR_STATE_INTERLOCK 0x04
+#define IPMI_LAST_PWR_STATE_FAULT 0x08
+#define IPMI_LAST_PWR_STATE_CMD_ON 0x10
+
+/*
+ * flags for the ichs_pwr_restore_policy field
+ */
+#define IPMI_PWR_POLICY_REMAIN_OFF 0x0
+#define IPMI_PWR_POLICY_RESTORE 0x1
+#define IPMI_PWR_POLICY_POWER_ON 0x2
+#define IPMI_PWR_POLICY_UNKNOWN 0x3
+
+typedef struct ipmi_chassis_status {
+ DECL_BITFIELD3(
+ ichs_current_pwr_state :5,
+ ichs_pwr_restore_policy :2,
+ __reserved1 :1);
+ DECL_BITFIELD2(
+ ichs_last_pwr_state :5,
+ __reserved2 :3);
+ DECL_BITFIELD7(
+ ichs_intrusion_asserted :1,
+ ichs_front_panel_disabled :1,
+ ichs_drive_fault_asserted :1,
+ ichs_fan_fault_asserted :1,
+ ichs_identify_state :2,
+ ichs_identify_supported :1,
+ __reserved3 :1);
+} ipmi_chassis_status_t;
+
+extern ipmi_chassis_status_t *ipmi_chassis_status(ipmi_handle_t *);
+
+/*
+ * See section 28.5
+ */
#define IPMI_CMD_CHASSIS_IDENTIFY 0x04
int ipmi_chassis_identify(ipmi_handle_t *, boolean_t);
diff --git a/usr/src/lib/libipmi/common/mapfile-vers b/usr/src/lib/libipmi/common/mapfile-vers
index 1f432b9a80..85526ddd84 100644
--- a/usr/src/lib/libipmi/common/mapfile-vers
+++ b/usr/src/lib/libipmi/common/mapfile-vers
@@ -23,6 +23,10 @@
#
#
+# Copyright (c) 2017, Joyent, Inc.
+#
+
+#
# MAPFILE HEADER START
#
# WARNING: STOP NOW. DO NOT MODIFY THIS FILE.
@@ -41,6 +45,7 @@ $mapfile_version 2
SYMBOL_VERSION SUNWprivate_1.1 {
global:
ipmi_chassis_identify;
+ ipmi_chassis_status;
ipmi_close;
ipmi_entity_iter;
ipmi_entity_iter_children;