static int fru_write(void) { struct ipmi_msg *msg; int len; /* We allocate FRU_DATA_SIZE + 5 bytes for the message: * - 3 bytes for the the write FRU command header * - FRU_DATA_SIZE bytes for FRU data * - 2 bytes for offset & bytes remaining count */ msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_WRITE_FRU, fru_write_complete, NULL, NULL, FRU_DATA_SIZE + 5, 2); if (!msg) return OPAL_RESOURCE; msg->data[0] = fru_dev_id; /* FRU Device ID */ msg->data[1] = 0x0; /* Offset LSB (we always write a new common header) */ msg->data[2] = 0x0; /* Offset MSB */ len = fru_add(&msg->data[3], FRU_DATA_SIZE); if (len < 0) return len; /* Three bytes for the actual FRU Data Command */ msg->data[WRITE_INDEX] = 0; msg->data[REMAINING] = len; msg->req_size = min(len + 3, IPMI_MAX_REQ_SIZE); return ipmi_queue_msg(msg); }
/* * Allocate IPMI message: * For normal event, allocate memory using ipmi_mkmsg and for PANIC * event, use pre-allocated buffer. */ static struct ipmi_msg *ipmi_sel_alloc_msg(struct errorlog *elog_buf) { struct ipmi_msg *msg = NULL; if (elog_buf->event_severity == OPAL_ERROR_PANIC) { /* Called before initialization completes */ if (ipmi_sel_panic_msg.msg == NULL) { ipmi_sel_init(); /* Try to allocate IPMI message */ if (ipmi_sel_panic_msg.msg == NULL) return NULL; } if (ipmi_sel_panic_msg.busy == true) return NULL; lock(&ipmi_sel_panic_msg.lock); msg = ipmi_sel_panic_msg.msg; ipmi_sel_panic_msg.busy = true; unlock(&ipmi_sel_panic_msg.lock); ipmi_init_msg(msg, IPMI_DEFAULT_INTERFACE, IPMI_RESERVE_SEL, ipmi_elog_poll, elog_buf, IPMI_MAX_REQ_SIZE, 2); } else { msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_RESERVE_SEL, ipmi_elog_poll, elog_buf, NULL, IPMI_MAX_REQ_SIZE, 2); } return msg; }
int ipmi_get_chassis_boot_opt_request(void) { int rc; struct ipmi_msg *msg; uint8_t req[] = { 0x62, /* OEM parameter (SBE Validation on astbmc) */ 0x00, /* no set selector */ 0x00, /* no block selector */ }; ipmi_sys_boot_opt = zalloc(sizeof(struct ipmi_sys_boot_opt)); assert(ipmi_sys_boot_opt); msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_CHASSIS_GET_BOOT_OPT, ipmi_get_chassis_boot_opt_resp, NULL, req, sizeof(req), sizeof(struct ipmi_sys_boot_opt)); if (!msg) { free(ipmi_sys_boot_opt); return OPAL_NO_MEM; } msg->error = ipmi_get_chassis_boot_opt_resp; prlog(PR_INFO, "IPMI: Requesting IPMI_CHASSIS_GET_BOOT_OPT\n"); rc = ipmi_queue_msg(msg); if (rc) { prlog(PR_ERR, "IPMI: Failed to queue IPMI_CHASSIS_GET_BOOT_OPT\n"); free(ipmi_sys_boot_opt); ipmi_free_msg(msg); return rc; } bmc_boot_opt_waiting = true; return rc; }
int ipmi_get_bmc_info_request(void) { int rc; struct ipmi_msg *msg; ipmi_dev_id = zalloc(sizeof(struct ipmi_dev_id)); assert(ipmi_dev_id); msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_BMC_GET_DEVICE_ID, ipmi_get_bmc_info_resp, NULL, NULL, 0, sizeof(struct ipmi_dev_id)); if (!msg) return OPAL_NO_MEM; msg->error = ipmi_get_bmc_info_resp; prlog(PR_INFO, "IPMI: Requesting IPMI_BMC_GET_DEVICE_ID\n"); rc = ipmi_queue_msg(msg); if (rc) { prlog(PR_ERR, "IPMI: Failed to queue IPMI_BMC_GET_DEVICE_ID\n"); ipmi_free_msg(msg); return rc; } bmc_info_waiting = true; return rc; }
static int64_t ipmi_get_sel_time(void) { struct ipmi_msg *msg; msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_GET_SEL_TIME, get_sel_time_complete, NULL, NULL, 0, 4); if (!msg) return OPAL_HARDWARE; msg->error = get_sel_time_error; return ipmi_queue_msg(msg); }
static void get_bt_caps(void) { struct ipmi_msg *bmc_caps; /* * Didn't sent a message, now is a good time to ask the BMC for its * capabilities. */ bmc_caps = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_GET_BT_CAPS, get_bt_caps_complete, NULL, NULL, 0, sizeof(struct bt_caps)); if (!bmc_caps) prerror("Couldn't create BMC BT capabilities msg\n"); if (bmc_caps && ipmi_queue_msg(bmc_caps)) prerror("Couldn't enqueue request for BMC BT capabilities\n"); /* Ignore errors, we'll fallback to using the defaults, no big deal */ }
static void set_wdt(uint8_t action, uint16_t count, uint8_t pretimeout) { struct ipmi_msg *ipmi_msg; ipmi_msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_SET_WDT, ipmi_wdt_complete, NULL, NULL, 6, 0); if (!ipmi_msg) { prerror("Unable to allocate set wdt message\n"); return; } ipmi_msg->error = ipmi_wdt_complete; ipmi_msg->data[0] = TIMER_USE_POST | TIMER_USE_DONT_LOG; /* Timer Use */ ipmi_msg->data[1] = action; /* Timer Actions */ ipmi_msg->data[2] = pretimeout; /* Pre-timeout Interval */ ipmi_msg->data[3] = 0; /* Timer Use Flags */ ipmi_msg->data[4] = count & 0xff; /* Initial countdown (lsb) */ ipmi_msg->data[5] = (count >> 8) & 0xff; /* Initial countdown (msb) */ ipmi_queue_msg(ipmi_msg); }
ipmi_msg->error = ipmi_wdt_complete; ipmi_msg->data[0] = TIMER_USE_POST | TIMER_USE_DONT_LOG; /* Timer Use */ ipmi_msg->data[1] = action; /* Timer Actions */ ipmi_msg->data[2] = pretimeout; /* Pre-timeout Interval */ ipmi_msg->data[3] = 0; /* Timer Use Flags */ ipmi_msg->data[4] = count & 0xff; /* Initial countdown (lsb) */ ipmi_msg->data[5] = (count >> 8) & 0xff; /* Initial countdown (msb) */ ipmi_queue_msg(ipmi_msg); } static void reset_wdt(struct timer *t __unused, void *data) { struct ipmi_msg *ipmi_msg; ipmi_msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_RESET_WDT, ipmi_wdt_complete, data, NULL, 0, 0); if (!ipmi_msg) { prerror("Unable to allocate reset wdt message\n"); return; } if (!data) ipmi_queue_msg_sync(ipmi_msg); else ipmi_queue_msg(ipmi_msg); } void ipmi_wdt_stop(void) { if (!wdt_stopped) { wdt_stopped = true;