IPMI base patch to fix channel handling and add polling
This patch fixes some problems with handling of channel detection in the driver. Some systems that are IPMI 1.5 do not implement the channel query command. Also, the interface has to be fully up before the command is ready.
This patch also adds a polling interface; this is required for situations where interrupts are not running, but the system must still issue IPMI commands, like when taking a crash dump.
It also updates the driver version to v32.
This patch is relative to 2.6.7-rc3-mm2. Please apply.
Signed-off-by Corey Minyard <[email protected]>
Thanks,
-Corey (recovering from vacation) Minyard
drivers/char/ipmi/ipmi_bt_sm.c +1 -1
@@ -31,7 +31,7 @@#include <linux/ipmi_msgdefs.h> /* for completion codes */ #include "ipmi_si_sm.h" -#define IPMI_BT_VERSION "v31" +#define IPMI_BT_VERSION "v32"static int bt_debug =0x00 ;/* Production value 0, see following flags */
drivers/char/ipmi/ipmi_devintf.c +1 -1
@@ -45,7 +45,7 @@#include <asm/semaphore.h> #include <linux/init.h> -#define IPMI_DEVINTF_VERSION "v31" +#define IPMI_DEVINTF_VERSION "v32"struct ipmi_file_private {
drivers/char/ipmi/ipmi_kcs_sm.c +1 -1
@@ -42,7 +42,7 @@#include <linux/ipmi_msgdefs.h> /* for completion codes */ #include "ipmi_si_sm.h" -#define IPMI_KCS_VERSION "v31" +#define IPMI_KCS_VERSION "v32"/* Set this if you want a printout of why the state machine was hosed when it gets hosed. */
drivers/char/ipmi/ipmi_msghandler.c +29 -2
@@ -46,7 +46,7 @@#include <linux/init.h> #include <linux/proc_fs.h> -#define IPMI_MSGHANDLER_VERSION "v31" +#define IPMI_MSGHANDLER_VERSION "v32"struct ipmi_recv_msg *ipmi_alloc_recv_msg (void );static int ipmi_init_msghandler (void );
@@ -1648,6 +1648,22 @@/* It's the one we want */ if (msg->rsp[2 ] !=0 ) {/* Got an error from the channel, just go on. */ + +if (msg->rsp[2 ] ==IPMI_INVALID_COMMAND_ERR ) { +/* If the MC does not support this +command, that is legal. We just +assume it has one IPMB at channel +zero. */ + intf->channels[0 ].medium + =IPMI_CHANNEL_MEDIUM_IPMB ; + intf->channels[0 ].protocol + =IPMI_CHANNEL_PROTOCOL_IPMB ; + rv = -ENOSYS ; + + intf->curr_channel =IPMI_MAX_CHANNELS ; +wake_up (&intf->waitq); + goto out; + } goto next_channel; }if (msg->rsp_size <6 ) {
@@ -1671,10 +1687,20 @@wake_up (&intf->waitq);printk (KERN_WARNING "ipmi_msghandler: Error sending" -"channel information: 0x%x\n" , +"channel information: %d\n" , rv); } } + out: +return ; +} + +void ipmi_poll_interface (ipmi_user_t user) +{ +ipmi_smi_t intf = user->intf; + +if (intf->handlers->poll) + intf->handlers->poll (intf->send_info); } int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
@@ -3154,6 +3180,7 @@EXPORT_SYMBOL (ipmi_request_settime);EXPORT_SYMBOL (ipmi_request_supply_msgs);EXPORT_SYMBOL (ipmi_request_with_source); +EXPORT_SYMBOL (ipmi_poll_interface);EXPORT_SYMBOL (ipmi_register_smi);EXPORT_SYMBOL (ipmi_unregister_smi);EXPORT_SYMBOL (ipmi_register_for_cmd);
drivers/char/ipmi/ipmi_si_intf.c +45 -16
126 lines not on this page · raw message
drivers/char/ipmi/ipmi_smic_sm.c +1 -1
@@ -46,7 +46,7 @@#include <linux/ipmi_msgdefs.h> /* for completion codes */ #include "ipmi_si_sm.h" -#define IPMI_SMIC_VERSION "v31" +#define IPMI_SMIC_VERSION "v32"/* smic_debug is a bit-field * SMIC_DEBUG_ENABLE - turned on for now
drivers/char/ipmi/ipmi_watchdog.c +3 -5
@@ -51,7 +51,7 @@#include <asm/apic.h> #endif -#define IPMI_WATCHDOG_VERSION "v31" +#define IPMI_WATCHDOG_VERSION "v32"/* * The IPMI command/response information for the watchdog timer.
@@ -883,14 +883,12 @@/* On a panic, if we have a panic timeout, make sure that the thing reboots, even if it hangs during that panic. */ -if (watchdog_user && !panic_event_handled && (panic_timeout >0 )) { +if (watchdog_user && !panic_event_handled) {/* Make sure the panic doesn't hang, and make sure we do this only once. */ panic_event_handled =1 ; - timeout = panic_timeout +120 ; -if (timeout >255 ) - timeout =255 ; + timeout =255 ; pretimeout =0 ; ipmi_watchdog_state =WDOG_TIMEOUT_RESET ;panic_halt_ipmi_set_timeout ();
include/linux/ipmi.h +10 -0
@@ -373,6 +373,16 @@ int priority);/* +* Do polling on the IPMI interface the user is attached to. 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 anyway. This is useful if you need to implement +* polling from the user like you need to send periodic watchdog pings +* from a crash dump, or something like that. +*/ +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 * at a time, you will get an EBUSY error if the command is already
include/linux/ipmi_msgdefs.h +1 -0
@@ -71,6 +71,7 @@#define IPMI_CC_NO_ERROR 0x00#define IPMI_NODE_BUSY_ERR 0xc0 +#define IPMI_INVALID_COMMAND_ERR 0xc1#define IPMI_ERR_MSG_TRUNCATED 0xc6#define IPMI_LOST_ARBITRATION_ERR 0x81#define IPMI_ERR_UNSPECIFIED 0xff
include/linux/ipmi_smi.h +4 -0
@@ -100,6 +100,10 @@out and that none are pending, and any new requests are run to completion immediately. */ void (*set_run_to_completion)(void *send_info,int run_to_completion); + +/* Called to poll for work to do. This is so upper layers can +poll for operations during things like crash dumps. */ +void (*poll)(void *send_info); };/* Add a low-level interface to the IPMI driver. */