linux-stable/include/uapi/linux/ipmi_msgdefs.h
Xianting Tian f8910ffa81 ipmi:msghandler: retry to get device id on an error
We fail to get the BMCS's device id with low probability when loading
the ipmi driver and it causes BMC device registration failed. When this
issue occurs we got below kernel prints:

  [Wed Sep  9 19:52:03 2020] ipmi_si IPI0001:00: IPMI message handler:
     device id demangle failed: -22
  [Wed Sep  9 19:52:03 2020] IPMI BT: using default values
  [Wed Sep  9 19:52:03 2020] IPMI BT: req2rsp=5 secs retries=2
  [Wed Sep  9 19:52:03 2020] ipmi_si IPI0001:00: Unable to get the
     device id: -5
  [Wed Sep  9 19:52:04 2020] ipmi_si IPI0001:00: Unable to register
     device: error -5

When this issue happens, we want to manually unload the driver and try to
load it again, but it can't be unloaded by 'rmmod' as it is already 'in
use'.

We add a print in handle_one_recv_msg(), when this issue happens,
the msg we received is "Recv: 1c 01 d5", which means the data_len is 1,
data[0] is 0xd5 (completion code), which means "bmc cannot execute
command.  Command, or request parameter(s), not supported in present
state".  Debug code:
	static int handle_one_recv_msg(struct ipmi_smi *intf,
                               struct ipmi_smi_msg *msg) {
        	printk("Recv: %*ph\n", msg->rsp_size, msg->rsp);
		... ...
	}
Then in ipmi_demangle_device_id(), it returned '-EINVAL' as 'data_len < 7'
and 'data[0] != 0'.

We created this patch to retry the get device id when this error
happens.  We reproduced this issue again and the retry succeed on the
first retry, we finally got the correct msg and then all is ok:
Recv: 1c 01 00 01 81 05 84 02 af db 07 00 01 00 b9 00 10 00

So use a retry machanism in this patch to give bmc more opportunity to
correctly response kernel when we received specific completion codes.

Signed-off-by: Xianting Tian <tian.xianting@h3c.com>
Message-Id: <20200915071817.4484-1-tian.xianting@h3c.com>
[Cleaned up the verbage a bit in the header and prints.]
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2020-09-15 09:57:45 -05:00

104 lines
3.3 KiB
C

/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/*
* ipmi_smi.h
*
* MontaVista IPMI system management interface
*
* Author: MontaVista Software, Inc.
* Corey Minyard <minyard@mvista.com>
* source@mvista.com
*
* Copyright 2002 MontaVista Software Inc.
*
*/
#ifndef __LINUX_IPMI_MSGDEFS_H
#define __LINUX_IPMI_MSGDEFS_H
/* Various definitions for IPMI messages used by almost everything in
the IPMI stack. */
/* NetFNs and commands used inside the IPMI stack. */
#define IPMI_NETFN_SENSOR_EVENT_REQUEST 0x04
#define IPMI_NETFN_SENSOR_EVENT_RESPONSE 0x05
#define IPMI_GET_EVENT_RECEIVER_CMD 0x01
#define IPMI_NETFN_APP_REQUEST 0x06
#define IPMI_NETFN_APP_RESPONSE 0x07
#define IPMI_GET_DEVICE_ID_CMD 0x01
#define IPMI_COLD_RESET_CMD 0x02
#define IPMI_WARM_RESET_CMD 0x03
#define IPMI_CLEAR_MSG_FLAGS_CMD 0x30
#define IPMI_GET_DEVICE_GUID_CMD 0x08
#define IPMI_GET_MSG_FLAGS_CMD 0x31
#define IPMI_SEND_MSG_CMD 0x34
#define IPMI_GET_MSG_CMD 0x33
#define IPMI_SET_BMC_GLOBAL_ENABLES_CMD 0x2e
#define IPMI_GET_BMC_GLOBAL_ENABLES_CMD 0x2f
#define IPMI_READ_EVENT_MSG_BUFFER_CMD 0x35
#define IPMI_GET_CHANNEL_INFO_CMD 0x42
/* Bit for BMC global enables. */
#define IPMI_BMC_RCV_MSG_INTR 0x01
#define IPMI_BMC_EVT_MSG_INTR 0x02
#define IPMI_BMC_EVT_MSG_BUFF 0x04
#define IPMI_BMC_SYS_LOG 0x08
#define IPMI_NETFN_STORAGE_REQUEST 0x0a
#define IPMI_NETFN_STORAGE_RESPONSE 0x0b
#define IPMI_ADD_SEL_ENTRY_CMD 0x44
#define IPMI_NETFN_FIRMWARE_REQUEST 0x08
#define IPMI_NETFN_FIRMWARE_RESPONSE 0x09
/* The default slave address */
#define IPMI_BMC_SLAVE_ADDR 0x20
/* The BT interface on high-end HP systems supports up to 255 bytes in
* one transfer. Its "virtual" BMC supports some commands that are longer
* than 128 bytes. Use the full 256, plus NetFn/LUN, Cmd, cCode, plus
* some overhead; it's not worth the effort to dynamically size this based
* on the results of the "Get BT Capabilities" command. */
#define IPMI_MAX_MSG_LENGTH 272 /* multiple of 16 */
#define IPMI_CC_NO_ERROR 0x00
#define IPMI_NODE_BUSY_ERR 0xc0
#define IPMI_INVALID_COMMAND_ERR 0xc1
#define IPMI_TIMEOUT_ERR 0xc3
#define IPMI_ERR_MSG_TRUNCATED 0xc6
#define IPMI_REQ_LEN_INVALID_ERR 0xc7
#define IPMI_REQ_LEN_EXCEEDED_ERR 0xc8
#define IPMI_DEVICE_IN_FW_UPDATE_ERR 0xd1
#define IPMI_DEVICE_IN_INIT_ERR 0xd2
#define IPMI_NOT_IN_MY_STATE_ERR 0xd5 /* IPMI 2.0 */
#define IPMI_LOST_ARBITRATION_ERR 0x81
#define IPMI_BUS_ERR 0x82
#define IPMI_NAK_ON_WRITE_ERR 0x83
#define IPMI_ERR_UNSPECIFIED 0xff
#define IPMI_CHANNEL_PROTOCOL_IPMB 1
#define IPMI_CHANNEL_PROTOCOL_ICMB 2
#define IPMI_CHANNEL_PROTOCOL_SMBUS 4
#define IPMI_CHANNEL_PROTOCOL_KCS 5
#define IPMI_CHANNEL_PROTOCOL_SMIC 6
#define IPMI_CHANNEL_PROTOCOL_BT10 7
#define IPMI_CHANNEL_PROTOCOL_BT15 8
#define IPMI_CHANNEL_PROTOCOL_TMODE 9
#define IPMI_CHANNEL_MEDIUM_IPMB 1
#define IPMI_CHANNEL_MEDIUM_ICMB10 2
#define IPMI_CHANNEL_MEDIUM_ICMB09 3
#define IPMI_CHANNEL_MEDIUM_8023LAN 4
#define IPMI_CHANNEL_MEDIUM_ASYNC 5
#define IPMI_CHANNEL_MEDIUM_OTHER_LAN 6
#define IPMI_CHANNEL_MEDIUM_PCI_SMBUS 7
#define IPMI_CHANNEL_MEDIUM_SMBUS1 8
#define IPMI_CHANNEL_MEDIUM_SMBUS2 9
#define IPMI_CHANNEL_MEDIUM_USB1 10
#define IPMI_CHANNEL_MEDIUM_USB2 11
#define IPMI_CHANNEL_MEDIUM_SYSINTF 12
#define IPMI_CHANNEL_MEDIUM_OEM_MIN 0x60
#define IPMI_CHANNEL_MEDIUM_OEM_MAX 0x7f
#endif /* __LINUX_IPMI_MSGDEFS_H */