diff options
-rw-r--r-- | sound/core/timer.c | 32 |
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 | ||
1772 | static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, | 1772 | static 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 | ||
1826 | static 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 | |||
1832 | static int snd_timer_user_fasync(int fd, struct file * file, int on) | 1838 | static 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; |