Esempio n. 1
0
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);
}
Esempio n. 2
0
/*
 * 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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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 */
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
	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;