diff options
Diffstat (limited to 'usr/src/lib/libipmi')
-rw-r--r-- | usr/src/lib/libipmi/common/ipmi_fru.c | 38 | ||||
-rw-r--r-- | usr/src/lib/libipmi/common/ipmi_misc.c | 34 | ||||
-rw-r--r-- | usr/src/lib/libipmi/common/libipmi.h | 56 | ||||
-rw-r--r-- | usr/src/lib/libipmi/common/mapfile-vers | 5 |
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; |