aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ipmi/ipmi_msghandler.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/ipmi/ipmi_msghandler.c')
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c46
1 files changed, 32 insertions, 14 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 0c81652eaba6..1813d0d198f1 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -54,7 +54,9 @@ static int ipmi_init_msghandler(void);
54 54
55static int initialized = 0; 55static int initialized = 0;
56 56
57static struct proc_dir_entry *proc_ipmi_root = NULL; 57#ifdef CONFIG_PROC_FS
58struct proc_dir_entry *proc_ipmi_root = NULL;
59#endif /* CONFIG_PROC_FS */
58 60
59#define MAX_EVENTS_IN_QUEUE 25 61#define MAX_EVENTS_IN_QUEUE 25
60 62
@@ -124,11 +126,13 @@ struct ipmi_channel
124 unsigned char protocol; 126 unsigned char protocol;
125}; 127};
126 128
129#ifdef CONFIG_PROC_FS
127struct ipmi_proc_entry 130struct ipmi_proc_entry
128{ 131{
129 char *name; 132 char *name;
130 struct ipmi_proc_entry *next; 133 struct ipmi_proc_entry *next;
131}; 134};
135#endif
132 136
133#define IPMI_IPMB_NUM_SEQ 64 137#define IPMI_IPMB_NUM_SEQ 64
134#define IPMI_MAX_CHANNELS 8 138#define IPMI_MAX_CHANNELS 8
@@ -156,10 +160,13 @@ struct ipmi_smi
156 struct ipmi_smi_handlers *handlers; 160 struct ipmi_smi_handlers *handlers;
157 void *send_info; 161 void *send_info;
158 162
163#ifdef CONFIG_PROC_FS
159 /* A list of proc entries for this interface. This does not 164 /* A list of proc entries for this interface. This does not
160 need a lock, only one thread creates it and only one thread 165 need a lock, only one thread creates it and only one thread
161 destroys it. */ 166 destroys it. */
167 spinlock_t proc_entry_lock;
162 struct ipmi_proc_entry *proc_entries; 168 struct ipmi_proc_entry *proc_entries;
169#endif
163 170
164 /* A table of sequence numbers for this interface. We use the 171 /* A table of sequence numbers for this interface. We use the
165 sequence numbers for IPMB messages that go out of the 172 sequence numbers for IPMB messages that go out of the
@@ -1470,8 +1477,9 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
1470 read_proc_t *read_proc, write_proc_t *write_proc, 1477 read_proc_t *read_proc, write_proc_t *write_proc,
1471 void *data, struct module *owner) 1478 void *data, struct module *owner)
1472{ 1479{
1473 struct proc_dir_entry *file;
1474 int rv = 0; 1480 int rv = 0;
1481#ifdef CONFIG_PROC_FS
1482 struct proc_dir_entry *file;
1475 struct ipmi_proc_entry *entry; 1483 struct ipmi_proc_entry *entry;
1476 1484
1477 /* Create a list element. */ 1485 /* Create a list element. */
@@ -1497,10 +1505,13 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
1497 file->write_proc = write_proc; 1505 file->write_proc = write_proc;
1498 file->owner = owner; 1506 file->owner = owner;
1499 1507
1508 spin_lock(&smi->proc_entry_lock);
1500 /* Stick it on the list. */ 1509 /* Stick it on the list. */
1501 entry->next = smi->proc_entries; 1510 entry->next = smi->proc_entries;
1502 smi->proc_entries = entry; 1511 smi->proc_entries = entry;
1512 spin_unlock(&smi->proc_entry_lock);
1503 } 1513 }
1514#endif /* CONFIG_PROC_FS */
1504 1515
1505 return rv; 1516 return rv;
1506} 1517}
@@ -1509,6 +1520,7 @@ static int add_proc_entries(ipmi_smi_t smi, int num)
1509{ 1520{
1510 int rv = 0; 1521 int rv = 0;
1511 1522
1523#ifdef CONFIG_PROC_FS
1512 sprintf(smi->proc_dir_name, "%d", num); 1524 sprintf(smi->proc_dir_name, "%d", num);
1513 smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root); 1525 smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root);
1514 if (!smi->proc_dir) 1526 if (!smi->proc_dir)
@@ -1531,14 +1543,17 @@ static int add_proc_entries(ipmi_smi_t smi, int num)
1531 rv = ipmi_smi_add_proc_entry(smi, "version", 1543 rv = ipmi_smi_add_proc_entry(smi, "version",
1532 version_file_read_proc, NULL, 1544 version_file_read_proc, NULL,
1533 smi, THIS_MODULE); 1545 smi, THIS_MODULE);
1546#endif /* CONFIG_PROC_FS */
1534 1547
1535 return rv; 1548 return rv;
1536} 1549}
1537 1550
1538static void remove_proc_entries(ipmi_smi_t smi) 1551static void remove_proc_entries(ipmi_smi_t smi)
1539{ 1552{
1553#ifdef CONFIG_PROC_FS
1540 struct ipmi_proc_entry *entry; 1554 struct ipmi_proc_entry *entry;
1541 1555
1556 spin_lock(&smi->proc_entry_lock);
1542 while (smi->proc_entries) { 1557 while (smi->proc_entries) {
1543 entry = smi->proc_entries; 1558 entry = smi->proc_entries;
1544 smi->proc_entries = entry->next; 1559 smi->proc_entries = entry->next;
@@ -1547,7 +1562,9 @@ static void remove_proc_entries(ipmi_smi_t smi)
1547 kfree(entry->name); 1562 kfree(entry->name);
1548 kfree(entry); 1563 kfree(entry);
1549 } 1564 }
1565 spin_unlock(&smi->proc_entry_lock);
1550 remove_proc_entry(smi->proc_dir_name, proc_ipmi_root); 1566 remove_proc_entry(smi->proc_dir_name, proc_ipmi_root);
1567#endif /* CONFIG_PROC_FS */
1551} 1568}
1552 1569
1553static int 1570static int
@@ -1694,6 +1711,9 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
1694 new_intf->seq_table[j].seqid = 0; 1711 new_intf->seq_table[j].seqid = 0;
1695 } 1712 }
1696 new_intf->curr_seq = 0; 1713 new_intf->curr_seq = 0;
1714#ifdef CONFIG_PROC_FS
1715 spin_lock_init(&(new_intf->proc_entry_lock));
1716#endif
1697 spin_lock_init(&(new_intf->waiting_msgs_lock)); 1717 spin_lock_init(&(new_intf->waiting_msgs_lock));
1698 INIT_LIST_HEAD(&(new_intf->waiting_msgs)); 1718 INIT_LIST_HEAD(&(new_intf->waiting_msgs));
1699 spin_lock_init(&(new_intf->events_lock)); 1719 spin_lock_init(&(new_intf->events_lock));
@@ -2747,16 +2767,13 @@ static struct timer_list ipmi_timer;
2747 the queue and this silliness can go away. */ 2767 the queue and this silliness can go away. */
2748#define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME)) 2768#define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME))
2749 2769
2750static volatile int stop_operation = 0; 2770static atomic_t stop_operation;
2751static volatile int timer_stopped = 0;
2752static unsigned int ticks_to_req_ev = IPMI_REQUEST_EV_TIME; 2771static unsigned int ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
2753 2772
2754static void ipmi_timeout(unsigned long data) 2773static void ipmi_timeout(unsigned long data)
2755{ 2774{
2756 if (stop_operation) { 2775 if (atomic_read(&stop_operation))
2757 timer_stopped = 1;
2758 return; 2776 return;
2759 }
2760 2777
2761 ticks_to_req_ev--; 2778 ticks_to_req_ev--;
2762 if (ticks_to_req_ev == 0) { 2779 if (ticks_to_req_ev == 0) {
@@ -2766,8 +2783,7 @@ static void ipmi_timeout(unsigned long data)
2766 2783
2767 ipmi_timeout_handler(IPMI_TIMEOUT_TIME); 2784 ipmi_timeout_handler(IPMI_TIMEOUT_TIME);
2768 2785
2769 ipmi_timer.expires += IPMI_TIMEOUT_JIFFIES; 2786 mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
2770 add_timer(&ipmi_timer);
2771} 2787}
2772 2788
2773 2789
@@ -3089,6 +3105,7 @@ static int ipmi_init_msghandler(void)
3089 ipmi_interfaces[i] = NULL; 3105 ipmi_interfaces[i] = NULL;
3090 } 3106 }
3091 3107
3108#ifdef CONFIG_PROC_FS
3092 proc_ipmi_root = proc_mkdir("ipmi", NULL); 3109 proc_ipmi_root = proc_mkdir("ipmi", NULL);
3093 if (!proc_ipmi_root) { 3110 if (!proc_ipmi_root) {
3094 printk(KERN_ERR PFX "Unable to create IPMI proc dir"); 3111 printk(KERN_ERR PFX "Unable to create IPMI proc dir");
@@ -3096,6 +3113,7 @@ static int ipmi_init_msghandler(void)
3096 } 3113 }
3097 3114
3098 proc_ipmi_root->owner = THIS_MODULE; 3115 proc_ipmi_root->owner = THIS_MODULE;
3116#endif /* CONFIG_PROC_FS */
3099 3117
3100 init_timer(&ipmi_timer); 3118 init_timer(&ipmi_timer);
3101 ipmi_timer.data = 0; 3119 ipmi_timer.data = 0;
@@ -3130,13 +3148,12 @@ static __exit void cleanup_ipmi(void)
3130 3148
3131 /* Tell the timer to stop, then wait for it to stop. This avoids 3149 /* Tell the timer to stop, then wait for it to stop. This avoids
3132 problems with race conditions removing the timer here. */ 3150 problems with race conditions removing the timer here. */
3133 stop_operation = 1; 3151 atomic_inc(&stop_operation);
3134 while (!timer_stopped) { 3152 del_timer_sync(&ipmi_timer);
3135 set_current_state(TASK_UNINTERRUPTIBLE);
3136 schedule_timeout(1);
3137 }
3138 3153
3154#ifdef CONFIG_PROC_FS
3139 remove_proc_entry(proc_ipmi_root->name, &proc_root); 3155 remove_proc_entry(proc_ipmi_root->name, &proc_root);
3156#endif /* CONFIG_PROC_FS */
3140 3157
3141 initialized = 0; 3158 initialized = 0;
3142 3159
@@ -3177,4 +3194,5 @@ EXPORT_SYMBOL(ipmi_get_my_address);
3177EXPORT_SYMBOL(ipmi_set_my_LUN); 3194EXPORT_SYMBOL(ipmi_set_my_LUN);
3178EXPORT_SYMBOL(ipmi_get_my_LUN); 3195EXPORT_SYMBOL(ipmi_get_my_LUN);
3179EXPORT_SYMBOL(ipmi_smi_add_proc_entry); 3196EXPORT_SYMBOL(ipmi_smi_add_proc_entry);
3197EXPORT_SYMBOL(proc_ipmi_root);
3180EXPORT_SYMBOL(ipmi_user_set_run_to_completion); 3198EXPORT_SYMBOL(ipmi_user_set_run_to_completion);