fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / include / linux / ipmi.h
index 75311f2..7a9db39 100644 (file)
@@ -35,6 +35,7 @@
 #define __LINUX_IPMI_H
 
 #include <linux/ipmi_msgdefs.h>
+#include <linux/compiler.h>
 
 /*
  * This file describes an interface to an IPMI driver.  You have to
@@ -124,7 +125,7 @@ struct ipmi_ipmb_addr
  * In this address, the remote_SWID is always the SWID the remote
  * message came from, or the SWID we are sending the message to.
  * local_SWID is always our SWID.  Note that having our SWID in the
- * message is a little wierd, but this is required.
+ * message is a little weird, but this is required.
  */
 #define IPMI_LAN_ADDR_TYPE             0x04
 struct ipmi_lan_addr
@@ -147,6 +148,13 @@ struct ipmi_lan_addr
 #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
@@ -155,6 +163,14 @@ struct ipmi_lan_addr
  * out).
  */
 struct ipmi_msg
+{
+       unsigned char  netfn;
+       unsigned char  cmd;
+       unsigned short data_len;
+       unsigned char  __user *data;
+};
+
+struct kernel_ipmi_msg
 {
        unsigned char  netfn;
        unsigned char  cmd;
@@ -192,6 +208,15 @@ struct ipmi_msg
    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__
 
@@ -200,6 +225,8 @@ struct ipmi_msg
  */
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/device.h>
+#include <linux/proc_fs.h>
 
 /* Opaque type for a IPMI message user.  One of these is needed to
    send and receive messages. */
@@ -223,12 +250,13 @@ struct ipmi_recv_msg
        ipmi_user_t      user;
        struct ipmi_addr addr;
        long             msgid;
-       struct ipmi_msg  msg;
+       struct kernel_ipmi_msg  msg;
 
        /* The user_msg_data is the data supplied when a message was
           sent, if this is a response to a sent message.  If this is
           not a response to a sent message, then user_msg_data will
-          be NULL. */
+          be NULL.  If the user above is NULL, then this will be the
+          intf. */
        void             *user_msg_data;
 
        /* Call this when done with the message.  It will presumably free
@@ -241,11 +269,7 @@ struct ipmi_recv_msg
 };
 
 /* Allocate and free the receive message. */
-static inline void ipmi_free_recv_msg(struct ipmi_recv_msg *msg)
-{
-       msg->done(msg);
-}
-struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
+void ipmi_free_recv_msg(struct ipmi_recv_msg *msg);
 
 struct ipmi_user_hndl
 {
@@ -286,39 +310,19 @@ void ipmi_get_version(ipmi_user_t   user,
    this user, so it will affect all users of this interface.  This is
    so some initialization code can come in and do the OEM-specific
    things it takes to determine your address (if not the BMC) and set
-   it for everyone else. */
-void ipmi_set_my_address(ipmi_user_t   user,
-                        unsigned char address);
-unsigned char ipmi_get_my_address(ipmi_user_t user);
-void ipmi_set_my_LUN(ipmi_user_t   user,
-                    unsigned char LUN);
-unsigned char ipmi_get_my_LUN(ipmi_user_t user);
-
-/*
- * Send a command request from the given user.  The address is the
- * proper address for the channel type.  If this is a command, then
- * the message response comes back, the receive handler for this user
- * will be called with the given msgid value in the recv msg.  If this
- * is a response to a command, then the msgid will be used as the
- * sequence number for the response (truncated if necessary), so when
- * sending a response you should use the sequence number you received
- * in the msgid field of the received command.  If the priority is >
- * 0, the message will go into a high-priority queue and be sent
- * first.  Otherwise, it goes into a normal-priority queue.
- * The user_msg_data field will be returned in any response to this
- * message.
- *
- * Note that if you send a response (with the netfn lower bit set),
- * you *will* get back a SEND_MSG response telling you what happened
- * when the response was sent.  You will not get back a response to
- * the message itself.
- */
-int ipmi_request(ipmi_user_t      user,
-                struct ipmi_addr *addr,
-                long             msgid,
-                struct ipmi_msg  *msg,
-                void             *user_msg_data,
-                int              priority);
+   it for everyone else.  Note that each channel can have its own address. */
+int ipmi_set_my_address(ipmi_user_t   user,
+                       unsigned int  channel,
+                       unsigned char address);
+int ipmi_get_my_address(ipmi_user_t   user,
+                       unsigned int  channel,
+                       unsigned char *address);
+int ipmi_set_my_LUN(ipmi_user_t   user,
+                   unsigned int  channel,
+                   unsigned char LUN);
+int ipmi_get_my_LUN(ipmi_user_t   user,
+                   unsigned int  channel,
+                   unsigned char *LUN);
 
 /*
  * Like ipmi_request, but lets you specify the number of retries and
@@ -336,24 +340,12 @@ int ipmi_request(ipmi_user_t      user,
 int ipmi_request_settime(ipmi_user_t      user,
                         struct ipmi_addr *addr,
                         long             msgid,
-                        struct ipmi_msg  *msg,
+                        struct kernel_ipmi_msg  *msg,
                         void             *user_msg_data,
                         int              priority,
                         int              max_retries,
                         unsigned int     retry_time_ms);
 
-/*
- * Like ipmi_request, but lets you specify the slave return address.
- */
-int ipmi_request_with_source(ipmi_user_t      user,
-                            struct ipmi_addr *addr,
-                            long             msgid,
-                            struct ipmi_msg  *msg,
-                            void             *user_msg_data,
-                            int              priority,
-                            unsigned char    source_address,
-                            unsigned char    source_lun);
-
 /*
  * Like ipmi_request, but with messages supplied.  This will not
  * allocate any memory, and the messages may be statically allocated
@@ -366,7 +358,7 @@ int ipmi_request_with_source(ipmi_user_t      user,
 int ipmi_request_supply_msgs(ipmi_user_t          user,
                             struct ipmi_addr     *addr,
                             long                 msgid,
-                            struct ipmi_msg      *msg,
+                            struct kernel_ipmi_msg *msg,
                             void                 *user_msg_data,
                             void                 *supplied_smi,
                             struct ipmi_recv_msg *supplied_recv,
@@ -374,18 +366,56 @@ int ipmi_request_supply_msgs(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);
+
+/*
+ * 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.
+ */
+int ipmi_get_maintenance_mode(ipmi_user_t user);
+int ipmi_set_maintenance_mode(ipmi_user_t user, int mode);
+
+/*
+ * Allow run-to-completion mode to be set for the interface of
+ * a specific user.
+ */
+void ipmi_user_set_run_to_completion(ipmi_user_t user, int val);
 
 /*
  * When the user is created, it will not receive IPMI events by
@@ -395,17 +425,6 @@ int ipmi_unregister_for_cmd(ipmi_user_t   user,
  */
 int ipmi_set_gets_events(ipmi_user_t user, int val);
 
-/*
- * Register the given user to handle all received IPMI commands.  This
- * will fail if anyone is registered as a command receiver or if
- * another is already registered to receive all commands.  NOTE THAT
- * THIS IS FOR EMULATION USERS ONLY, DO NOT USER THIS FOR NORMAL
- * STUFF.
- */
-int ipmi_register_all_cmd_rcvr(ipmi_user_t user);
-int ipmi_unregister_all_cmd_rcvr(ipmi_user_t user);
-
-
 /*
  * Called when a new SMI is registered.  This will also be called on
  * every existing interface when a new watcher is registered with
@@ -423,7 +442,7 @@ struct ipmi_smi_watcher
           the watcher list.  So you can add and remove users from the
           IPMI interface, send messages, etc., but you cannot add
           or remove SMI watchers or SMI interfaces. */
-       void (*new_smi)(int if_num);
+       void (*new_smi)(int if_num, struct device *dev);
        void (*smi_gone)(int if_num);
 };
 
@@ -439,9 +458,6 @@ unsigned int ipmi_addr_length(int addr_type);
 /* Validate that the given IPMI address is valid. */
 int ipmi_validate_addr(struct ipmi_addr *addr, int len);
 
-/* Return 1 if the given addresses are equal, 0 if not. */
-int ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2);
-
 #endif /* __KERNEL__ */
 
 
@@ -488,7 +504,7 @@ int ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2);
 /* Messages sent to the interface are this format. */
 struct ipmi_req
 {
-       unsigned char *addr; /* Address to send the message to. */
+       unsigned char __user *addr; /* Address to send the message to. */
        unsigned int  addr_len;
 
        long    msgid; /* The sequence number for the message.  This
@@ -539,7 +555,7 @@ struct ipmi_recv
        int     recv_type; /* Is this a command, response or an
                              asyncronous event. */
 
-       unsigned char *addr;    /* Address the message was from is put
+       unsigned char __user *addr;    /* Address the message was from is put
                                   here.  The caller must supply the
                                   memory. */
        unsigned int  addr_len; /* The size of the address buffer.
@@ -603,6 +619,36 @@ struct ipmi_cmdspec
 #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
@@ -619,6 +665,16 @@ struct ipmi_cmdspec
  * 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
+{
+       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)
+/* 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)
 #define IPMICTL_SET_MY_LUN_CMD         _IOR(IPMI_IOC_MAGIC, 19, unsigned int)
@@ -638,4 +694,11 @@ struct ipmi_timing_parms
 #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 */