>From a3dcd3ce65c4072acd707a000ba30ff917d52ef3 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Fri, 29 Nov 2013 18:13:45 -0600 Subject: [PATCH] IPMI: Start the timer properly in certain situations If using interrupt, or in some cases with the IPMI thread, the IPMI timer would not be started to time out operations, resulting in the driver operation hanging. Signed-off-by: Corey Minyard --- drivers/char/ipmi/ipmi_si_intf.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 68c5ef5..a8dfd94 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -981,6 +981,13 @@ static int ipmi_thread_busy_wait(enum si_sm_result smi_result, return 1; } +static void ipmi_start_timer_if_necessary(struct smi_info *smi_info) +{ + if (!timer_pending(&smi_info->si_timer)) { + mod_timer(&smi_info->si_timer, jiffies + SI_TIMEOUT_JIFFIES); + smi_info->last_timeout_jiffies = jiffies; + } +} /* * A busy-waiting loop for speeding up IPMI operation. @@ -1014,8 +1021,10 @@ static int ipmi_thread(void *data) schedule(); else if (smi_result == SI_SM_IDLE) schedule_timeout_interruptible(100); - else + else { + ipmi_start_timer_if_necessary(smi_info); schedule_timeout_interruptible(1); + } } return 0; } @@ -1118,7 +1127,8 @@ static irqreturn_t si_irq_handler(int irq, void *data) do_gettimeofday(&t); printk(KERN_DEBUG "**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec); #endif - smi_event_handler(smi_info, 0); + if (smi_event_handler(smi_info, 0) != SI_SM_IDLE) + ipmi_start_timer_if_necessary(smi_info); spin_unlock_irqrestore(&(smi_info->si_lock), flags); return IRQ_HANDLED; } @@ -1979,7 +1989,8 @@ static u32 ipmi_acpi_gpe(acpi_handle gpe_device, do_gettimeofday(&t); printk("**ACPI_GPE: %d.%9.9d\n", t.tv_sec, t.tv_usec); #endif - smi_event_handler(smi_info, 0); + if (smi_event_handler(smi_info, 0) != SI_SM_IDLE) + ipmi_start_timer_if_necessary(smi_info); spin_unlock_irqrestore(&(smi_info->si_lock), flags); return ACPI_INTERRUPT_HANDLED; -- 1.8.3.1