/* SPDX-License-Identifier: GPL-2.0+ */ /* * ipmi_smi.h * * MontaVista IPMI system management interface * * Author: MontaVista Software, Inc. * Corey Minyard <[email protected]> * [email protected] * * Copyright 2002 MontaVista Software Inc. * */ #ifndef __LINUX_IPMI_SMI_H #define __LINUX_IPMI_SMI_H #include <linux/ipmi_msgdefs.h> #include <linux/proc_fs.h> #include <linux/platform_device.h> #include <linux/ipmi.h> struct device; /* * This files describes the interface for IPMI system management interface * drivers to bind into the IPMI message handler. */ /* Structure for the low-level drivers. */ struct ipmi_smi; /* * Flags for set_check_watch() below. Tells if the SMI should be * waiting for watchdog timeouts, commands and/or messages. */ #define IPMI_WATCH_MASK_CHECK_MESSAGES … #define IPMI_WATCH_MASK_CHECK_WATCHDOG … #define IPMI_WATCH_MASK_CHECK_COMMANDS … /* * SMI messages * * When communicating with an SMI, messages come in two formats: * * * Normal (to a BMC over a BMC interface) * * * IPMB (over a IPMB to another MC) * * When normal, commands are sent using the format defined by a * standard message over KCS (NetFn must be even): * * +-----------+-----+------+ * | NetFn/LUN | Cmd | Data | * +-----------+-----+------+ * * And responses, similarly, with an completion code added (NetFn must * be odd): * * +-----------+-----+------+------+ * | NetFn/LUN | Cmd | CC | Data | * +-----------+-----+------+------+ * * With normal messages, only commands are sent and only responses are * received. * * In IPMB mode, we are acting as an IPMB device. Commands will be in * the following format (NetFn must be even): * * +-------------+------+-------------+-----+------+ * | NetFn/rsLUN | Addr | rqSeq/rqLUN | Cmd | Data | * +-------------+------+-------------+-----+------+ * * Responses will using the following format: * * +-------------+------+-------------+-----+------+------+ * | NetFn/rqLUN | Addr | rqSeq/rsLUN | Cmd | CC | Data | * +-------------+------+-------------+-----+------+------+ * * This is similar to the format defined in the IPMB manual section * 2.11.1 with the checksums and the first address removed. Also, the * address is always the remote address. * * IPMB messages can be commands and responses in both directions. * Received commands are handled as received commands from the message * queue. */ enum ipmi_smi_msg_type { … }; /* * Messages to/from the lower layer. The smi interface will take one * of these to send. After the send has occurred and a response has * been received, it will report this same data structure back up to * the upper layer. If an error occurs, it should fill in the * response with an error code in the completion code location. When * asynchronous data is received, one of these is allocated, the * data_size is set to zero and the response holds the data from the * get message or get event command that the interface initiated. * Note that it is the interfaces responsibility to detect * asynchronous data and messages and request them from the * interface. */ struct ipmi_smi_msg { … }; #define INIT_IPMI_SMI_MSG(done_handler) … struct ipmi_smi_handlers { … }; struct ipmi_device_id { … }; #define ipmi_version_major(v) … #define ipmi_version_minor(v) … /* * Take a pointer to an IPMI response and extract device id information from * it. @netfn is in the IPMI_NETFN_ format, so may need to be shifted from * a SI response. */ static inline int ipmi_demangle_device_id(uint8_t netfn, uint8_t cmd, const unsigned char *data, unsigned int data_len, struct ipmi_device_id *id) { … } /* * Add a low-level interface to the IPMI driver. Note that if the * interface doesn't know its slave address, it should pass in zero. * The low-level interface should not deliver any messages to the * upper layer until the start_processing() function in the handlers * is called, and the lower layer must get the interface from that * call. */ int ipmi_add_smi(struct module *owner, const struct ipmi_smi_handlers *handlers, void *send_info, struct device *dev, unsigned char slave_addr); #define ipmi_register_smi(handlers, send_info, dev, slave_addr) … /* * Remove a low-level interface from the IPMI driver. This will * return an error if the interface is still in use by a user. */ void ipmi_unregister_smi(struct ipmi_smi *intf); /* * The lower layer reports received messages through this interface. * The data_size should be zero if this is an asynchronous message. If * the lower layer gets an error sending a message, it should format * an error response in the message response. */ void ipmi_smi_msg_received(struct ipmi_smi *intf, struct ipmi_smi_msg *msg); /* The lower layer received a watchdog pre-timeout on interface. */ void ipmi_smi_watchdog_pretimeout(struct ipmi_smi *intf); struct ipmi_smi_msg *ipmi_alloc_smi_msg(void); static inline void ipmi_free_smi_msg(struct ipmi_smi_msg *msg) { … } #endif /* __LINUX_IPMI_SMI_H */