aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ipmi/ipmi_devintf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/ipmi/ipmi_devintf.c')
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c48
1 files changed, 44 insertions, 4 deletions
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 7c0684deea06..932feedda262 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -90,7 +90,7 @@ static unsigned int ipmi_poll(struct file *file, poll_table *wait)
90 90
91 spin_lock_irqsave(&priv->recv_msg_lock, flags); 91 spin_lock_irqsave(&priv->recv_msg_lock, flags);
92 92
93 if (! list_empty(&(priv->recv_msgs))) 93 if (!list_empty(&(priv->recv_msgs)))
94 mask |= (POLLIN | POLLRDNORM); 94 mask |= (POLLIN | POLLRDNORM);
95 95
96 spin_unlock_irqrestore(&priv->recv_msg_lock, flags); 96 spin_unlock_irqrestore(&priv->recv_msg_lock, flags);
@@ -789,21 +789,53 @@ MODULE_PARM_DESC(ipmi_major, "Sets the major number of the IPMI device. By"
789 " interface. Other values will set the major device number" 789 " interface. Other values will set the major device number"
790 " to that value."); 790 " to that value.");
791 791
792/* Keep track of the devices that are registered. */
793struct ipmi_reg_list {
794 dev_t dev;
795 struct list_head link;
796};
797static LIST_HEAD(reg_list);
798static DEFINE_MUTEX(reg_list_mutex);
799
792static struct class *ipmi_class; 800static struct class *ipmi_class;
793 801
794static void ipmi_new_smi(int if_num) 802static void ipmi_new_smi(int if_num, struct device *device)
795{ 803{
796 dev_t dev = MKDEV(ipmi_major, if_num); 804 dev_t dev = MKDEV(ipmi_major, if_num);
805 struct ipmi_reg_list *entry;
797 806
798 devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR, 807 devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR,
799 "ipmidev/%d", if_num); 808 "ipmidev/%d", if_num);
800 809
801 class_device_create(ipmi_class, NULL, dev, NULL, "ipmi%d", if_num); 810 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
811 if (!entry) {
812 printk(KERN_ERR "ipmi_devintf: Unable to create the"
813 " ipmi class device link\n");
814 return;
815 }
816 entry->dev = dev;
817
818 mutex_lock(&reg_list_mutex);
819 class_device_create(ipmi_class, NULL, dev, device, "ipmi%d", if_num);
820 list_add(&entry->link, &reg_list);
821 mutex_unlock(&reg_list_mutex);
802} 822}
803 823
804static void ipmi_smi_gone(int if_num) 824static void ipmi_smi_gone(int if_num)
805{ 825{
806 class_device_destroy(ipmi_class, MKDEV(ipmi_major, if_num)); 826 dev_t dev = MKDEV(ipmi_major, if_num);
827 struct ipmi_reg_list *entry;
828
829 mutex_lock(&reg_list_mutex);
830 list_for_each_entry(entry, &reg_list, link) {
831 if (entry->dev == dev) {
832 list_del(&entry->link);
833 kfree(entry);
834 break;
835 }
836 }
837 class_device_destroy(ipmi_class, dev);
838 mutex_unlock(&reg_list_mutex);
807 devfs_remove("ipmidev/%d", if_num); 839 devfs_remove("ipmidev/%d", if_num);
808} 840}
809 841
@@ -856,6 +888,14 @@ module_init(init_ipmi_devintf);
856 888
857static __exit void cleanup_ipmi(void) 889static __exit void cleanup_ipmi(void)
858{ 890{
891 struct ipmi_reg_list *entry, *entry2;
892 mutex_lock(&reg_list_mutex);
893 list_for_each_entry_safe(entry, entry2, &reg_list, link) {
894 list_del(&entry->link);
895 class_device_destroy(ipmi_class, entry->dev);
896 kfree(entry);
897 }
898 mutex_unlock(&reg_list_mutex);
859 class_destroy(ipmi_class); 899 class_destroy(ipmi_class);
860 ipmi_smi_watcher_unregister(&smi_watcher); 900 ipmi_smi_watcher_unregister(&smi_watcher);
861 devfs_remove(DEVICE_NAME); 901 devfs_remove(DEVICE_NAME);