* applications and another for userland applications. The
* capabilities are basically the same for both interface, although
* the interfaces are somewhat different. The stuff in the
- * #ifdef KERNEL below is the in-kernel interface. The userland
+ * #ifdef __KERNEL__ below is the in-kernel interface. The userland
* interface is defined later in the file. */
* work for sockets.
*/
#define IPMI_MAX_ADDR_SIZE 32
-struct ipmi_addr
-{
+struct ipmi_addr {
/* Try to take these from the "Channel Medium Type" table
in section 6.5 of the IPMI 1.5 manual. */
int addr_type;
* 0), or IPMC_BMC_CHANNEL if communicating directly with the BMC.
*/
#define IPMI_SYSTEM_INTERFACE_ADDR_TYPE 0x0c
-struct ipmi_system_interface_addr
-{
+struct ipmi_system_interface_addr {
int addr_type;
short channel;
unsigned char lun;
/* An IPMB Address. */
#define IPMI_IPMB_ADDR_TYPE 0x01
/* Used for broadcast get device id as described in section 17.9 of the
- IPMI 1.5 manual. */
+ IPMI 1.5 manual. */
#define IPMI_IPMB_BROADCAST_ADDR_TYPE 0x41
-struct ipmi_ipmb_addr
-{
+struct ipmi_ipmb_addr {
int addr_type;
short channel;
unsigned char slave_addr;
* message is a little weird, but this is required.
*/
#define IPMI_LAN_ADDR_TYPE 0x04
-struct ipmi_lan_addr
-{
+struct ipmi_lan_addr {
int addr_type;
short channel;
unsigned char privilege;
#define IPMI_BMC_CHANNEL 0xf
#define IPMI_NUM_CHANNELS 0x10
+/*
+ * Used to signify an "all channel" bitmask. This is more than the
+ * actual number of channels because this is used in userland and
+ * will cover us if the number of channels is extended.
+ */
+#define IPMI_CHAN_ALL (~0)
+
/*
* A raw IPMI message without any addressing. This covers both
* byte of data in the response (as the spec shows the messages laid
* out).
*/
-struct ipmi_msg
-{
+struct ipmi_msg {
unsigned char netfn;
unsigned char cmd;
unsigned short data_len;
unsigned char __user *data;
};
-struct kernel_ipmi_msg
-{
+struct kernel_ipmi_msg {
unsigned char netfn;
unsigned char cmd;
unsigned short data_len;
code as the first byte of the incoming data, unlike a response. */
+/*
+ * Modes for ipmi_set_maint_mode() and the userland IOCTL. The AUTO
+ * setting is the default and means it will be set on certain
+ * commands. Hard setting it on and off will override automatic
+ * operation.
+ */
+#define IPMI_MAINTENANCE_MODE_AUTO 0
+#define IPMI_MAINTENANCE_MODE_OFF 1
+#define IPMI_MAINTENANCE_MODE_ON 2
#ifdef __KERNEL__
#include <linux/list.h>
#include <linux/module.h>
#include <linux/device.h>
-
-#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
-extern struct proc_dir_entry *proc_ipmi_root;
-#endif /* CONFIG_PROC_FS */
/* Opaque type for a IPMI message user. One of these is needed to
send and receive messages. */
* used after the message is delivered, so the upper layer may use the
* link to build a linked list, if it likes.
*/
-struct ipmi_recv_msg
-{
+struct ipmi_recv_msg {
struct list_head link;
/* The type of message as defined in the "Receive Types"
- defines above. */
+ defines above. */
int recv_type;
ipmi_user_t user;
/* Allocate and free the receive message. */
void ipmi_free_recv_msg(struct ipmi_recv_msg *msg);
-struct ipmi_user_hndl
-{
- /* Routine type to call when a message needs to be routed to
+struct ipmi_user_hndl {
+ /* Routine type to call when a message needs to be routed to
the upper layer. This will be called with some locks held,
the only IPMI routines that can be called are ipmi_request
and the alloc/free operations. The handler_data is the
struct ipmi_recv_msg *supplied_recv,
int priority);
+/*
+ * Poll the IPMI interface for the user. This causes the IPMI code to
+ * do an immediate check for information from the driver and handle
+ * anything that is immediately pending. This will not block in any
+ * way. This is useful if you need to spin waiting for something to
+ * happen in the IPMI driver.
+ */
+void ipmi_poll_interface(ipmi_user_t user);
+
/*
* When commands come in to the SMS, the user can register to receive
- * them. Only one user can be listening on a specific netfn/cmd pair
+ * them. Only one user can be listening on a specific netfn/cmd/chan tuple
* at a time, you will get an EBUSY error if the command is already
* registered. If a command is received that does not have a user
* registered, the driver will automatically return the proper
- * error.
+ * error. Channels are specified as a bitfield, use IPMI_CHAN_ALL to
+ * mean all channels.
*/
int ipmi_register_for_cmd(ipmi_user_t user,
unsigned char netfn,
- unsigned char cmd);
+ unsigned char cmd,
+ unsigned int chans);
int ipmi_unregister_for_cmd(ipmi_user_t user,
unsigned char netfn,
- unsigned char cmd);
+ unsigned char cmd,
+ unsigned int chans);
/*
- * Allow run-to-completion mode to be set for the interface of
- * a specific user.
+ * Go into a mode where the driver will not autonomously attempt to do
+ * things with the interface. It will still respond to attentions and
+ * interrupts, and it will expect that commands will complete. It
+ * will not automatcially check for flags, events, or things of that
+ * nature.
+ *
+ * This is primarily used for firmware upgrades. The idea is that
+ * when you go into firmware upgrade mode, you do this operation
+ * and the driver will not attempt to do anything but what you tell
+ * it or what the BMC asks for.
+ *
+ * Note that if you send a command that resets the BMC, the driver
+ * will still expect a response from that command. So the BMC should
+ * reset itself *after* the response is sent. Resetting before the
+ * response is just silly.
+ *
+ * If in auto maintenance mode, the driver will automatically go into
+ * maintenance mode for 30 seconds if it sees a cold reset, a warm
+ * reset, or a firmware NetFN. This means that code that uses only
+ * firmware NetFN commands to do upgrades will work automatically
+ * without change, assuming it sends a message every 30 seconds or
+ * less.
+ *
+ * See the IPMI_MAINTENANCE_MODE_xxx defines for what the mode means.
*/
-void ipmi_user_set_run_to_completion(ipmi_user_t user, int val);
+int ipmi_get_maintenance_mode(ipmi_user_t user);
+int ipmi_set_maintenance_mode(ipmi_user_t user, int mode);
/*
* When the user is created, it will not receive IPMI events by
* every existing interface when a new watcher is registered with
* ipmi_smi_watcher_register().
*/
-struct ipmi_smi_watcher
-{
+struct ipmi_smi_watcher {
struct list_head link;
/* You must set the owner to the current module, if you are in
/* Messages sent to the interface are this format. */
-struct ipmi_req
-{
+struct ipmi_req {
unsigned char __user *addr; /* Address to send the message to. */
unsigned int addr_len;
/* Messages sent to the interface with timing parameters are this
format. */
-struct ipmi_req_settime
-{
+struct ipmi_req_settime {
struct ipmi_req req;
/* See ipmi_request_settime() above for details on these
- values. */
+ values. */
int retries;
unsigned int retry_time_ms;
};
struct ipmi_req_settime)
/* Messages received from the interface are this format. */
-struct ipmi_recv
-{
+struct ipmi_recv {
int recv_type; /* Is this a command, response or an
asyncronous event. */
struct ipmi_recv)
/* Register to get commands from other entities on this interface. */
-struct ipmi_cmdspec
-{
+struct ipmi_cmdspec {
unsigned char netfn;
unsigned char cmd;
};
-/*
+/*
* Register to receive a specific command. error values:
* - EFAULT - an address supplied was invalid.
* - EBUSY - The netfn/cmd supplied was already in use.
#define IPMICTL_UNREGISTER_FOR_CMD _IOR(IPMI_IOC_MAGIC, 15, \
struct ipmi_cmdspec)
-/*
+/*
+ * Register to get commands from other entities on specific channels.
+ * This way, you can only listen on specific channels, or have messages
+ * from some channels go to one place and other channels to someplace
+ * else. The chans field is a bitmask, (1 << channel) for each channel.
+ * It may be IPMI_CHAN_ALL for all channels.
+ */
+struct ipmi_cmdspec_chans {
+ unsigned int netfn;
+ unsigned int cmd;
+ unsigned int chans;
+};
+
+/*
+ * Register to receive a specific command on specific channels. error values:
+ * - EFAULT - an address supplied was invalid.
+ * - EBUSY - One of the netfn/cmd/chans supplied was already in use.
+ * - ENOMEM - could not allocate memory for the entry.
+ */
+#define IPMICTL_REGISTER_FOR_CMD_CHANS _IOR(IPMI_IOC_MAGIC, 28, \
+ struct ipmi_cmdspec_chans)
+/*
+ * Unregister some netfn/cmd/chans. error values:
+ * - EFAULT - an address supplied was invalid.
+ * - ENOENT - None of the netfn/cmd/chans were found registered for this user.
+ */
+#define IPMICTL_UNREGISTER_FOR_CMD_CHANS _IOR(IPMI_IOC_MAGIC, 29, \
+ struct ipmi_cmdspec_chans)
+
+/*
* Set whether this interface receives events. Note that the first
* user registered for events will get all pending events for the
* interface. error values:
* things it takes to determine your address (if not the BMC) and set
* it for everyone else. You should probably leave the LUN alone.
*/
-struct ipmi_channel_lun_address_set
-{
+struct ipmi_channel_lun_address_set {
unsigned short channel;
unsigned char value;
};
-#define IPMICTL_SET_MY_CHANNEL_ADDRESS_CMD _IOR(IPMI_IOC_MAGIC, 24, struct ipmi_channel_lun_address_set)
-#define IPMICTL_GET_MY_CHANNEL_ADDRESS_CMD _IOR(IPMI_IOC_MAGIC, 25, struct ipmi_channel_lun_address_set)
-#define IPMICTL_SET_MY_CHANNEL_LUN_CMD _IOR(IPMI_IOC_MAGIC, 26, struct ipmi_channel_lun_address_set)
-#define IPMICTL_GET_MY_CHANNEL_LUN_CMD _IOR(IPMI_IOC_MAGIC, 27, struct ipmi_channel_lun_address_set)
+#define IPMICTL_SET_MY_CHANNEL_ADDRESS_CMD \
+ _IOR(IPMI_IOC_MAGIC, 24, struct ipmi_channel_lun_address_set)
+#define IPMICTL_GET_MY_CHANNEL_ADDRESS_CMD \
+ _IOR(IPMI_IOC_MAGIC, 25, struct ipmi_channel_lun_address_set)
+#define IPMICTL_SET_MY_CHANNEL_LUN_CMD \
+ _IOR(IPMI_IOC_MAGIC, 26, struct ipmi_channel_lun_address_set)
+#define IPMICTL_GET_MY_CHANNEL_LUN_CMD \
+ _IOR(IPMI_IOC_MAGIC, 27, struct ipmi_channel_lun_address_set)
/* Legacy interfaces, these only set IPMB 0. */
#define IPMICTL_SET_MY_ADDRESS_CMD _IOR(IPMI_IOC_MAGIC, 17, unsigned int)
#define IPMICTL_GET_MY_ADDRESS_CMD _IOR(IPMI_IOC_MAGIC, 18, unsigned int)
* Get/set the default timing values for an interface. You shouldn't
* generally mess with these.
*/
-struct ipmi_timing_parms
-{
+struct ipmi_timing_parms {
int retries;
unsigned int retry_time_ms;
};
#define IPMICTL_GET_TIMING_PARMS_CMD _IOR(IPMI_IOC_MAGIC, 23, \
struct ipmi_timing_parms)
+/*
+ * Set the maintenance mode. See ipmi_set_maintenance_mode() above
+ * for a description of what this does.
+ */
+#define IPMICTL_GET_MAINTENANCE_MODE_CMD _IOR(IPMI_IOC_MAGIC, 30, int)
+#define IPMICTL_SET_MAINTENANCE_MODE_CMD _IOW(IPMI_IOC_MAGIC, 31, int)
+
#endif /* __LINUX_IPMI_H */