diff options
Diffstat (limited to 'drivers/char/nvram.c')
| -rw-r--r-- | drivers/char/nvram.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index fdbcc9fd6d3..9df78e2cc45 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -94,13 +94,12 @@ /* Note that *all* calls to CMOS_READ and CMOS_WRITE must be done with * rtc_lock held. Due to the index-port/data-port design of the RTC, we * don't want two different things trying to get to it at once. (e.g. the - * periodic 11 min sync from time.c vs. this driver.) + * periodic 11 min sync from kernel/time/ntp.c vs. this driver.) */ #include <linux/types.h> #include <linux/errno.h> #include <linux/miscdevice.h> -#include <linux/slab.h> #include <linux/ioport.h> #include <linux/fcntl.h> #include <linux/mc146818rtc.h> @@ -110,10 +109,10 @@ #include <linux/spinlock.h> #include <linux/io.h> #include <linux/uaccess.h> -#include <linux/smp_lock.h> +#include <linux/mutex.h> -#include <asm/system.h> +static DEFINE_MUTEX(nvram_mutex); static DEFINE_SPINLOCK(nvram_state_lock); static int nvram_open_cnt; /* #times opened */ static int nvram_open_mode; /* special open modes */ @@ -224,6 +223,8 @@ static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) case 2: offset += NVRAM_BYTES; break; + default: + return -EINVAL; } return (offset >= 0) ? (file->f_pos = offset) : -EINVAL; @@ -297,8 +298,8 @@ checksum_err: return -EIO; } -static int nvram_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long nvram_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { int i; @@ -309,6 +310,7 @@ static int nvram_ioctl(struct inode *inode, struct file *file, if (!capable(CAP_SYS_ADMIN)) return -EACCES; + mutex_lock(&nvram_mutex); spin_lock_irq(&rtc_lock); for (i = 0; i < NVRAM_BYTES; ++i) @@ -316,6 +318,7 @@ static int nvram_ioctl(struct inode *inode, struct file *file, __nvram_set_checksum(); spin_unlock_irq(&rtc_lock); + mutex_unlock(&nvram_mutex); return 0; case NVRAM_SETCKS: @@ -324,9 +327,11 @@ static int nvram_ioctl(struct inode *inode, struct file *file, if (!capable(CAP_SYS_ADMIN)) return -EACCES; + mutex_lock(&nvram_mutex); spin_lock_irq(&rtc_lock); __nvram_set_checksum(); spin_unlock_irq(&rtc_lock); + mutex_unlock(&nvram_mutex); return 0; default: @@ -336,14 +341,12 @@ static int nvram_ioctl(struct inode *inode, struct file *file, static int nvram_open(struct inode *inode, struct file *file) { - lock_kernel(); spin_lock(&nvram_state_lock); if ((nvram_open_cnt && (file->f_flags & O_EXCL)) || (nvram_open_mode & NVRAM_EXCL) || ((file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE))) { spin_unlock(&nvram_state_lock); - unlock_kernel(); return -EBUSY; } @@ -354,7 +357,6 @@ static int nvram_open(struct inode *inode, struct file *file) nvram_open_cnt++; spin_unlock(&nvram_state_lock); - unlock_kernel(); return 0; } @@ -426,7 +428,7 @@ static const struct file_operations nvram_fops = { .llseek = nvram_llseek, .read = nvram_read, .write = nvram_write, - .ioctl = nvram_ioctl, + .unlocked_ioctl = nvram_ioctl, .open = nvram_open, .release = nvram_release, }; |
