aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ipmi/ipmi_si_intf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/ipmi/ipmi_si_intf.c')
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c51
1 files changed, 39 insertions, 12 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 25a1436a4291..444ea548dfe3 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -257,6 +257,9 @@ struct smi_info {
257 /* Used to gracefully stop the timer without race conditions. */ 257 /* Used to gracefully stop the timer without race conditions. */
258 atomic_t stop_operation; 258 atomic_t stop_operation;
259 259
260 /* Are we waiting for the events, pretimeouts, received msgs? */
261 atomic_t need_watch;
262
260 /* 263 /*
261 * The driver will disable interrupts when it gets into a 264 * The driver will disable interrupts when it gets into a
262 * situation where it cannot handle messages due to lack of 265 * situation where it cannot handle messages due to lack of
@@ -862,6 +865,19 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
862 return si_sm_result; 865 return si_sm_result;
863} 866}
864 867
868static void check_start_timer_thread(struct smi_info *smi_info)
869{
870 if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) {
871 smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
872
873 if (smi_info->thread)
874 wake_up_process(smi_info->thread);
875
876 start_next_msg(smi_info);
877 smi_event_handler(smi_info, 0);
878 }
879}
880
865static void sender(void *send_info, 881static void sender(void *send_info,
866 struct ipmi_smi_msg *msg, 882 struct ipmi_smi_msg *msg,
867 int priority) 883 int priority)
@@ -915,15 +931,7 @@ static void sender(void *send_info,
915 else 931 else
916 list_add_tail(&msg->link, &smi_info->xmit_msgs); 932 list_add_tail(&msg->link, &smi_info->xmit_msgs);
917 933
918 if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) { 934 check_start_timer_thread(smi_info);
919 smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
920
921 if (smi_info->thread)
922 wake_up_process(smi_info->thread);
923
924 start_next_msg(smi_info);
925 smi_event_handler(smi_info, 0);
926 }
927 spin_unlock_irqrestore(&smi_info->si_lock, flags); 935 spin_unlock_irqrestore(&smi_info->si_lock, flags);
928} 936}
929 937
@@ -1023,9 +1031,15 @@ static int ipmi_thread(void *data)
1023 ; /* do nothing */ 1031 ; /* do nothing */
1024 else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait) 1032 else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait)
1025 schedule(); 1033 schedule();
1026 else if (smi_result == SI_SM_IDLE) 1034 else if (smi_result == SI_SM_IDLE) {
1027 schedule_timeout_interruptible(100); 1035 if (atomic_read(&smi_info->need_watch)) {
1028 else 1036 schedule_timeout_interruptible(100);
1037 } else {
1038 /* Wait to be woken up when we are needed. */
1039 __set_current_state(TASK_INTERRUPTIBLE);
1040 schedule();
1041 }
1042 } else
1029 schedule_timeout_interruptible(1); 1043 schedule_timeout_interruptible(1);
1030 } 1044 }
1031 return 0; 1045 return 0;
@@ -1061,6 +1075,17 @@ static void request_events(void *send_info)
1061 atomic_set(&smi_info->req_events, 1); 1075 atomic_set(&smi_info->req_events, 1);
1062} 1076}
1063 1077
1078static void set_need_watch(void *send_info, int enable)
1079{
1080 struct smi_info *smi_info = send_info;
1081 unsigned long flags;
1082
1083 atomic_set(&smi_info->need_watch, enable);
1084 spin_lock_irqsave(&smi_info->si_lock, flags);
1085 check_start_timer_thread(smi_info);
1086 spin_unlock_irqrestore(&smi_info->si_lock, flags);
1087}
1088
1064static int initialized; 1089static int initialized;
1065 1090
1066static void smi_timeout(unsigned long data) 1091static void smi_timeout(unsigned long data)
@@ -1212,6 +1237,7 @@ static struct ipmi_smi_handlers handlers = {
1212 .get_smi_info = get_smi_info, 1237 .get_smi_info = get_smi_info,
1213 .sender = sender, 1238 .sender = sender,
1214 .request_events = request_events, 1239 .request_events = request_events,
1240 .set_need_watch = set_need_watch,
1215 .set_maintenance_mode = set_maintenance_mode, 1241 .set_maintenance_mode = set_maintenance_mode,
1216 .set_run_to_completion = set_run_to_completion, 1242 .set_run_to_completion = set_run_to_completion,
1217 .poll = poll, 1243 .poll = poll,
@@ -3352,6 +3378,7 @@ static int try_smi_init(struct smi_info *new_smi)
3352 3378
3353 new_smi->interrupt_disabled = 1; 3379 new_smi->interrupt_disabled = 1;
3354 atomic_set(&new_smi->stop_operation, 0); 3380 atomic_set(&new_smi->stop_operation, 0);
3381 atomic_set(&new_smi->need_watch, 0);
3355 new_smi->intf_num = smi_num; 3382 new_smi->intf_num = smi_num;
3356 smi_num++; 3383 smi_num++;
3357 3384