summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/core/timer.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 9241784dfe7d..3810ee8f1205 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -73,7 +73,7 @@ struct snd_timer_user {
73 struct timespec tstamp; /* trigger tstamp */ 73 struct timespec tstamp; /* trigger tstamp */
74 wait_queue_head_t qchange_sleep; 74 wait_queue_head_t qchange_sleep;
75 struct fasync_struct *fasync; 75 struct fasync_struct *fasync;
76 struct mutex tread_sem; 76 struct mutex ioctl_lock;
77}; 77};
78 78
79/* list of timers */ 79/* list of timers */
@@ -1253,7 +1253,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file)
1253 return -ENOMEM; 1253 return -ENOMEM;
1254 spin_lock_init(&tu->qlock); 1254 spin_lock_init(&tu->qlock);
1255 init_waitqueue_head(&tu->qchange_sleep); 1255 init_waitqueue_head(&tu->qchange_sleep);
1256 mutex_init(&tu->tread_sem); 1256 mutex_init(&tu->ioctl_lock);
1257 tu->ticks = 1; 1257 tu->ticks = 1;
1258 tu->queue_size = 128; 1258 tu->queue_size = 128;
1259 tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read), 1259 tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
@@ -1273,8 +1273,10 @@ static int snd_timer_user_release(struct inode *inode, struct file *file)
1273 if (file->private_data) { 1273 if (file->private_data) {
1274 tu = file->private_data; 1274 tu = file->private_data;
1275 file->private_data = NULL; 1275 file->private_data = NULL;
1276 mutex_lock(&tu->ioctl_lock);
1276 if (tu->timeri) 1277 if (tu->timeri)
1277 snd_timer_close(tu->timeri); 1278 snd_timer_close(tu->timeri);
1279 mutex_unlock(&tu->ioctl_lock);
1278 kfree(tu->queue); 1280 kfree(tu->queue);
1279 kfree(tu->tqueue); 1281 kfree(tu->tqueue);
1280 kfree(tu); 1282 kfree(tu);
@@ -1512,7 +1514,6 @@ static int snd_timer_user_tselect(struct file *file,
1512 int err = 0; 1514 int err = 0;
1513 1515
1514 tu = file->private_data; 1516 tu = file->private_data;
1515 mutex_lock(&tu->tread_sem);
1516 if (tu->timeri) { 1517 if (tu->timeri) {
1517 snd_timer_close(tu->timeri); 1518 snd_timer_close(tu->timeri);
1518 tu->timeri = NULL; 1519 tu->timeri = NULL;
@@ -1556,7 +1557,6 @@ static int snd_timer_user_tselect(struct file *file,
1556 } 1557 }
1557 1558
1558 __err: 1559 __err:
1559 mutex_unlock(&tu->tread_sem);
1560 return err; 1560 return err;
1561} 1561}
1562 1562
@@ -1769,7 +1769,7 @@ enum {
1769 SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), 1769 SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23),
1770}; 1770};
1771 1771
1772static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, 1772static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd,
1773 unsigned long arg) 1773 unsigned long arg)
1774{ 1774{
1775 struct snd_timer_user *tu; 1775 struct snd_timer_user *tu;
@@ -1786,17 +1786,11 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
1786 { 1786 {
1787 int xarg; 1787 int xarg;
1788 1788
1789 mutex_lock(&tu->tread_sem); 1789 if (tu->timeri) /* too late */
1790 if (tu->timeri) { /* too late */
1791 mutex_unlock(&tu->tread_sem);
1792 return -EBUSY; 1790 return -EBUSY;
1793 } 1791 if (get_user(xarg, p))
1794 if (get_user(xarg, p)) {
1795 mutex_unlock(&tu->tread_sem);
1796 return -EFAULT; 1792 return -EFAULT;
1797 }
1798 tu->tread = xarg ? 1 : 0; 1793 tu->tread = xarg ? 1 : 0;
1799 mutex_unlock(&tu->tread_sem);
1800 return 0; 1794 return 0;
1801 } 1795 }
1802 case SNDRV_TIMER_IOCTL_GINFO: 1796 case SNDRV_TIMER_IOCTL_GINFO:
@@ -1829,6 +1823,18 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
1829 return -ENOTTY; 1823 return -ENOTTY;
1830} 1824}
1831 1825
1826static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
1827 unsigned long arg)
1828{
1829 struct snd_timer_user *tu = file->private_data;
1830 long ret;
1831
1832 mutex_lock(&tu->ioctl_lock);
1833 ret = __snd_timer_user_ioctl(file, cmd, arg);
1834 mutex_unlock(&tu->ioctl_lock);
1835 return ret;
1836}
1837
1832static int snd_timer_user_fasync(int fd, struct file * file, int on) 1838static int snd_timer_user_fasync(int fd, struct file * file, int on)
1833{ 1839{
1834 struct snd_timer_user *tu; 1840 struct snd_timer_user *tu;