diff options
Diffstat (limited to 'drivers/char/ipmi/ipmi_devintf.c')
| -rw-r--r-- | drivers/char/ipmi/ipmi_devintf.c | 63 |
1 files changed, 46 insertions, 17 deletions
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 64e1c169e82..ec318bf434a 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -34,8 +34,8 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/errno.h> -#include <asm/system.h> #include <linux/poll.h> +#include <linux/sched.h> #include <linux/spinlock.h> #include <linux/slab.h> #include <linux/ipmi.h> @@ -43,7 +43,6 @@ #include <linux/init.h> #include <linux/device.h> #include <linux/compat.h> -#include <linux/smp_lock.h> struct ipmi_file_private { @@ -58,6 +57,7 @@ struct ipmi_file_private unsigned int default_retry_time_ms; }; +static DEFINE_MUTEX(ipmi_mutex); static void file_receive_handler(struct ipmi_recv_msg *msg, void *handler_data) { @@ -101,9 +101,9 @@ static int ipmi_fasync(int fd, struct file *file, int on) struct ipmi_file_private *priv = file->private_data; int result; - lock_kernel(); /* could race against open() otherwise */ + mutex_lock(&ipmi_mutex); /* could race against open() otherwise */ result = fasync_helper(fd, file, on, &priv->fasync_queue); - unlock_kernel(); + mutex_unlock(&ipmi_mutex); return (result); } @@ -124,7 +124,7 @@ static int ipmi_open(struct inode *inode, struct file *file) if (!priv) return -ENOMEM; - lock_kernel(); + mutex_lock(&ipmi_mutex); priv->file = file; rv = ipmi_create_user(if_num, @@ -149,7 +149,7 @@ static int ipmi_open(struct inode *inode, struct file *file) priv->default_retry_time_ms = 0; out: - unlock_kernel(); + mutex_unlock(&ipmi_mutex); return rv; } @@ -162,8 +162,6 @@ static int ipmi_release(struct inode *inode, struct file *file) if (rv) return rv; - ipmi_fasync (-1, file, 0); - /* FIXME - free the messages in the list. */ kfree(priv); @@ -229,8 +227,7 @@ static int handle_send_req(ipmi_user_t user, return rv; } -static int ipmi_ioctl(struct inode *inode, - struct file *file, +static int ipmi_ioctl(struct file *file, unsigned int cmd, unsigned long data) { @@ -631,6 +628,23 @@ static int ipmi_ioctl(struct inode *inode, return rv; } +/* + * Note: it doesn't make sense to take the BKL here but + * not in compat_ipmi_ioctl. -arnd + */ +static long ipmi_unlocked_ioctl(struct file *file, + unsigned int cmd, + unsigned long data) +{ + int ret; + + mutex_lock(&ipmi_mutex); + ret = ipmi_ioctl(file, cmd, data); + mutex_unlock(&ipmi_mutex); + + return ret; +} + #ifdef CONFIG_COMPAT /* @@ -796,6 +810,7 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd, struct ipmi_recv __user *precv64; struct ipmi_recv recv64; + memset(&recv64, 0, sizeof(recv64)); if (get_compat_ipmi_recv(&recv64, compat_ptr(arg))) return -EFAULT; @@ -803,7 +818,7 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd, if (copy_to_user(precv64, &recv64, sizeof(recv64))) return -EFAULT; - rc = ipmi_ioctl(filep->f_path.dentry->d_inode, filep, + rc = ipmi_ioctl(filep, ((cmd == COMPAT_IPMICTL_RECEIVE_MSG) ? IPMICTL_RECEIVE_MSG : IPMICTL_RECEIVE_MSG_TRUNC), @@ -820,21 +835,34 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd, return rc; } default: - return ipmi_ioctl(filep->f_path.dentry->d_inode, filep, cmd, arg); + return ipmi_ioctl(filep, cmd, arg); } } + +static long unlocked_compat_ipmi_ioctl(struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int ret; + + mutex_lock(&ipmi_mutex); + ret = compat_ipmi_ioctl(filep, cmd, arg); + mutex_unlock(&ipmi_mutex); + + return ret; +} #endif static const struct file_operations ipmi_fops = { .owner = THIS_MODULE, - .ioctl = ipmi_ioctl, + .unlocked_ioctl = ipmi_unlocked_ioctl, #ifdef CONFIG_COMPAT - .compat_ioctl = compat_ipmi_ioctl, + .compat_ioctl = unlocked_compat_ipmi_ioctl, #endif .open = ipmi_open, .release = ipmi_release, .fasync = ipmi_fasync, .poll = ipmi_poll, + .llseek = noop_llseek, }; #define DEVICE_NAME "ipmidev" @@ -871,7 +899,7 @@ static void ipmi_new_smi(int if_num, struct device *device) entry->dev = dev; mutex_lock(®_list_mutex); - device_create_drvdata(ipmi_class, device, dev, NULL, "ipmi%d", if_num); + device_create(ipmi_class, device, dev, NULL, "ipmi%d", if_num); list_add(&entry->link, ®_list); mutex_unlock(®_list_mutex); } @@ -900,7 +928,7 @@ static struct ipmi_smi_watcher smi_watcher = .smi_gone = ipmi_smi_gone, }; -static __init int init_ipmi_devintf(void) +static int __init init_ipmi_devintf(void) { int rv; @@ -938,7 +966,7 @@ static __init int init_ipmi_devintf(void) } module_init(init_ipmi_devintf); -static __exit void cleanup_ipmi(void) +static void __exit cleanup_ipmi(void) { struct ipmi_reg_list *entry, *entry2; mutex_lock(®_list_mutex); @@ -957,3 +985,4 @@ module_exit(cleanup_ipmi); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>"); MODULE_DESCRIPTION("Linux device interface for the IPMI message handler."); +MODULE_ALIAS("platform:ipmi_si"); |
