summaryrefslogtreecommitdiff
path: root/lib/ipmi_picmg.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ipmi_picmg.c')
-rw-r--r--lib/ipmi_picmg.c147
1 files changed, 76 insertions, 71 deletions
diff --git a/lib/ipmi_picmg.c b/lib/ipmi_picmg.c
index 7a66aa5..f47577e 100644
--- a/lib/ipmi_picmg.c
+++ b/lib/ipmi_picmg.c
@@ -417,27 +417,6 @@ is_led_color(const char *argv_ptr, uint8_t *led_color_ptr)
lprintf(LOG_ERR, "LED Color must be from ranges: <1..6>, <0xE..0xF>");
return (-1);
}
-/* is_led_duration - wrapper to convert user input into integer.
- * LED duration range is <1..127>
- *
- * @argv_ptr: source string to convert from; usually argv
- * @enable_ptr: pointer where to store result
- * returns: zero on success, other values mean error
- */
-int
-is_led_duration(const char *argv_ptr, uint8_t *led_duration_ptr)
-{
- if (!argv_ptr || !led_duration_ptr) {
- lprintf(LOG_ERR, "is_led_duration(): invalid argument(s).");
- return (-1);
- }
- if (str2uchar(argv_ptr, led_duration_ptr) == 0
- && *led_duration_ptr > 0 && *led_duration_ptr <= 127) {
- return 0;
- }
- lprintf(LOG_ERR, "Given LED Duration '%s' is invalid", argv_ptr);
- return (-1);
-}
/* is_led_function - wrapper to convert user input into integer.
* LED functions, however, might differ by OEM:
* - 0x00 - off override
@@ -772,21 +751,19 @@ ipmi_picmg_fru_activation_policy_set(struct ipmi_intf * intf, int argc, char **
if (is_fru_id(argv[0], &msg_data[1]) != 0) {
return (-1);
}
- if (str2uchar(argv[1], &msg_data[2]) != 0 || msg_data[2] > 1) {
+ if (str2uchar(argv[1], &msg_data[2]) != 0 || msg_data[2] > 3) {
/* FRU Lock Mask */
lprintf(LOG_ERR, "Given FRU Lock Mask '%s' is invalid.",
argv[1]);
return (-1);
}
- if (str2uchar(argv[2], &msg_data[3]) != 0 || msg_data[3] > 1) {
+ if (str2uchar(argv[2], &msg_data[3]) != 0 || msg_data[3] > 3) {
/* FRU Act Policy */
lprintf(LOG_ERR,
"Given FRU Activation Policy '%s' is invalid.",
argv[2]);
return (-1);
}
- msg_data[2]&= 0x03;
- msg_data[3]&= 0x03;
rsp = intf->sendrecv(intf, &req);
@@ -1363,19 +1340,55 @@ ipmi_picmg_set_led_state(struct ipmi_intf * intf, int argc, char ** argv)
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = PICMG_SET_FRU_LED_STATE_CMD;
- req.msg.data = msg_data;
+ req.msg.cmd = PICMG_SET_FRU_LED_STATE_CMD;
+ req.msg.data = msg_data;
req.msg.data_len = 6;
msg_data[0] = 0x00; /* PICMG identifier */
if (is_fru_id(argv[0], &msg_data[1]) != 0
|| is_led_id(argv[1], &msg_data[2]) != 0
|| is_led_function(argv[2], &msg_data[3]) != 0
- || is_led_duration(argv[3], &msg_data[4]) != 0
|| is_led_color(argv[4], &msg_data[5]) != 0) {
return (-1);
}
+ /* Validating the LED duration is not as simple as the other arguments, as
+ * the range of valid durations depends on the LED function. From the spec:
+ *
+ * ``On-duration: LED on-time in tens of milliseconds if (1 <= Byte 4 <= FAh)
+ * Lamp Test time in hundreds of milliseconds if (Byte 4 = FBh). Lamp Test
+ * time value must be less than 128. Other values when Byte 4 = FBh are
+ * reserved. Otherwise, this field is ignored and shall be set to 0h.''
+ *
+ * If we're doing a lamp test, then the allowed values are 0 -> 127.
+ * Otherwise, the allowed values are 0 -> 255. However, if the function is
+ * not a lamp test (0xFB) and outside the range 0x01 -> 0xFA then the value
+ * should be set to 0.
+ *
+ * Start by checking we have a parameter.
+ */
+ if (!argv[3]) {
+ lprintf(LOG_ERR, "LED Duration: invalid argument(s).");
+ return (-1);
+ }
+ /* Next check we have a number. */
+ if (str2uchar(argv[3], &msg_data[4]) != 0) {
+ lprintf(LOG_ERR, "Given LED Duration '%s' is invalid", argv[3]);
+ return (-1);
+ }
+ /* If we have a lamp test, ensure it's not too long a duration. */
+ if (msg_data[3] == 0xFB && msg_data[4] > 127) {
+ lprintf(LOG_ERR, "Given LED Duration '%s' is invalid", argv[3]);
+ return (-1);
+ }
+ /* If we're outside the range that allows durations, set the duration to 0.
+ * Warn the user that we're doing this.
+ */
+ if (msg_data[4] != 0 && (msg_data[3] == 0 || msg_data[3] > 0xFB)) {
+ lprintf(LOG_WARN, "Setting LED Duration '%s' to '0'", argv[3]);
+ msg_data[4] = 0;
+ }
+
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
@@ -1745,18 +1758,8 @@ ipmi_picmg_clk_set(struct ipmi_intf * intf, int argc, char ** argv)
}
}
-#if 1
-printf("## ID: %d\n", msg_data[1]);
-printf("## index: %d\n", msg_data[2]);
-printf("## setting: 0x%02x\n", msg_data[3]);
-printf("## family: %d\n", msg_data[4]);
-printf("## acc: %d\n", msg_data[5]);
-printf("## freq: %ld\n", freq );
-printf("## res: %d\n", msg_data[10]);
-#endif
rsp = intf->sendrecv(intf, &req);
-
if (!rsp) {
lprintf(LOG_ERR, "No valid response received.");
return -1;
@@ -2137,8 +2140,8 @@ ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv)
lprintf(LOG_NOTICE,
" 252: LED restore to local control");
lprintf(LOG_NOTICE, " 255: LED ON override");
- lprintf(LOG_NOTICE,
- " <duration> 1 - 127: LED Lamp Test / on duration");
+ lprintf(LOG_NOTICE, " <duration> 0 - 127: LED Lamp Test duration");
+ lprintf(LOG_NOTICE, " 0 - 255: LED Lamp ON duration");
lprintf(LOG_NOTICE, " <color> 0: reserved");
lprintf(LOG_NOTICE, " 1: BLUE");
lprintf(LOG_NOTICE, " 2: RED");
@@ -2335,37 +2338,39 @@ picmg_discover(struct ipmi_intf *intf) {
struct ipmi_rq req;
struct ipmi_rs *rsp;
char msg_data;
+ uint8_t picmg_avail = 0;
- if (intf->picmg_avail == 0) {
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD;
- msg_data = 0x00;
- req.msg.data = &msg_data;
- req.msg.data_len = 1;
- msg_data = 0;
-
- lprintf(LOG_DEBUG, "Running Get PICMG Properties my_addr %#x, transit %#x, target %#x",
- intf->my_addr, intf->transit_addr, intf->target_addr);
- rsp = intf->sendrecv(intf, &req);
- if (rsp && !rsp->ccode) {
- if ( (rsp->data[0] == 0) &&
- ((rsp->data[1] & 0x0F) == PICMG_ATCA_MAJOR_VERSION
- || (rsp->data[1] & 0x0F) == PICMG_AMC_MAJOR_VERSION) ) {
- intf->picmg_avail = 1;
- lprintf(LOG_DEBUG, "Discovered PICMG Extension %d.%d",
- (rsp->data[1] & 0x0f), (rsp->data[1] >> 4));
- }
- } else {
- if (rsp == NULL) {
- lprintf(LOG_DEBUG,"No Response from Get PICMG Properties");
- } else {
- lprintf(LOG_DEBUG,"Error Response %#x from Get PICMG Properities", rsp->ccode);
- }
- }
- }
- if (intf->picmg_avail == 0) {
- lprintf(LOG_DEBUG, "No PICMG Extenstion discovered");
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD;
+ msg_data = 0x00;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+ msg_data = 0;
+
+ lprintf(LOG_INFO, "Running Get PICMG Properties my_addr %#x, transit %#x, target %#x",
+ intf->my_addr, intf->transit_addr, intf->target_addr);
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ lprintf(LOG_INFO,"No response from Get PICMG Properties");
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_INFO,"Error response %#x from Get PICMG Properities",
+ rsp->ccode);
+ } else if (rsp->data_len < 4) {
+ lprintf(LOG_INFO,"Invalid Get PICMG Properties response length %d",
+ rsp->data_len);
+ } else if (rsp->data[0] != 0) {
+ lprintf(LOG_INFO,"Invalid Get PICMG Properties group extension %#x",
+ rsp->data[0]);
+ } else if ((rsp->data[1] & 0x0F) != PICMG_ATCA_MAJOR_VERSION
+ && (rsp->data[1] & 0x0F) != PICMG_AMC_MAJOR_VERSION) {
+ lprintf(LOG_INFO,"Unknown PICMG Extension Version %d.%d",
+ (rsp->data[1] & 0x0F), (rsp->data[1] >> 4));
+ } else {
+ picmg_avail = 1;
+ lprintf(LOG_INFO, "Discovered PICMG Extension Version %d.%d",
+ (rsp->data[1] & 0x0f), (rsp->data[1] >> 4));
}
- return intf->picmg_avail;
+
+ return picmg_avail;
}