aboutsummaryrefslogtreecommitdiffstats
path: root/sound/oss/au1550_ac97.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/oss/au1550_ac97.c')
-rw-r--r--sound/oss/au1550_ac97.c91
1 files changed, 52 insertions, 39 deletions
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
index c1070e33b32f..c4a4cdc07ab9 100644
--- a/sound/oss/au1550_ac97.c
+++ b/sound/oss/au1550_ac97.c
@@ -43,6 +43,7 @@
43#include <linux/sound.h> 43#include <linux/sound.h>
44#include <linux/slab.h> 44#include <linux/slab.h>
45#include <linux/soundcard.h> 45#include <linux/soundcard.h>
46#include <linux/smp_lock.h>
46#include <linux/init.h> 47#include <linux/init.h>
47#include <linux/interrupt.h> 48#include <linux/interrupt.h>
48#include <linux/kernel.h> 49#include <linux/kernel.h>
@@ -162,19 +163,10 @@ ld2(unsigned int x)
162static void 163static void
163au1550_delay(int msec) 164au1550_delay(int msec)
164{ 165{
165 unsigned long tmo;
166 signed long tmo2;
167
168 if (in_interrupt()) 166 if (in_interrupt())
169 return; 167 return;
170 168
171 tmo = jiffies + (msec * HZ) / 1000; 169 schedule_timeout_uninterruptible(msecs_to_jiffies(msec));
172 for (;;) {
173 tmo2 = tmo - jiffies;
174 if (tmo2 <= 0)
175 break;
176 schedule_timeout(tmo2);
177 }
178} 170}
179 171
180static u16 172static u16
@@ -807,7 +799,9 @@ au1550_llseek(struct file *file, loff_t offset, int origin)
807static int 799static int
808au1550_open_mixdev(struct inode *inode, struct file *file) 800au1550_open_mixdev(struct inode *inode, struct file *file)
809{ 801{
802 lock_kernel();
810 file->private_data = &au1550_state; 803 file->private_data = &au1550_state;
804 unlock_kernel();
811 return 0; 805 return 0;
812} 806}
813 807
@@ -824,22 +818,26 @@ mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
824 return codec->mixer_ioctl(codec, cmd, arg); 818 return codec->mixer_ioctl(codec, cmd, arg);
825} 819}
826 820
827static int 821static long
828au1550_ioctl_mixdev(struct inode *inode, struct file *file, 822au1550_ioctl_mixdev(struct file *file, unsigned int cmd, unsigned long arg)
829 unsigned int cmd, unsigned long arg)
830{ 823{
831 struct au1550_state *s = (struct au1550_state *)file->private_data; 824 struct au1550_state *s = (struct au1550_state *)file->private_data;
832 struct ac97_codec *codec = s->codec; 825 struct ac97_codec *codec = s->codec;
826 int ret;
833 827
834 return mixdev_ioctl(codec, cmd, arg); 828 lock_kernel();
829 ret = mixdev_ioctl(codec, cmd, arg);
830 unlock_kernel();
831
832 return ret;
835} 833}
836 834
837static /*const */ struct file_operations au1550_mixer_fops = { 835static /*const */ struct file_operations au1550_mixer_fops = {
838 owner:THIS_MODULE, 836 .owner = THIS_MODULE,
839 llseek:au1550_llseek, 837 .llseek = au1550_llseek,
840 ioctl:au1550_ioctl_mixdev, 838 .unlocked_ioctl = au1550_ioctl_mixdev,
841 open:au1550_open_mixdev, 839 .open = au1550_open_mixdev,
842 release:au1550_release_mixdev, 840 .release = au1550_release_mixdev,
843}; 841};
844 842
845static int 843static int
@@ -1343,8 +1341,7 @@ dma_count_done(struct dmabuf *db)
1343 1341
1344 1342
1345static int 1343static int
1346au1550_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 1344au1550_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1347 unsigned long arg)
1348{ 1345{
1349 struct au1550_state *s = (struct au1550_state *)file->private_data; 1346 struct au1550_state *s = (struct au1550_state *)file->private_data;
1350 unsigned long flags; 1347 unsigned long flags;
@@ -1780,6 +1777,17 @@ au1550_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
1780 return mixdev_ioctl(s->codec, cmd, arg); 1777 return mixdev_ioctl(s->codec, cmd, arg);
1781} 1778}
1782 1779
1780static long
1781au1550_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1782{
1783 int ret;
1784
1785 lock_kernel();
1786 ret = au1550_ioctl(file, cmd, arg);
1787 unlock_kernel();
1788
1789 return ret;
1790}
1783 1791
1784static int 1792static int
1785au1550_open(struct inode *inode, struct file *file) 1793au1550_open(struct inode *inode, struct file *file)
@@ -1797,21 +1805,22 @@ au1550_open(struct inode *inode, struct file *file)
1797#endif 1805#endif
1798 1806
1799 file->private_data = s; 1807 file->private_data = s;
1808 lock_kernel();
1800 /* wait for device to become free */ 1809 /* wait for device to become free */
1801 mutex_lock(&s->open_mutex); 1810 mutex_lock(&s->open_mutex);
1802 while (s->open_mode & file->f_mode) { 1811 while (s->open_mode & file->f_mode) {
1803 if (file->f_flags & O_NONBLOCK) { 1812 ret = -EBUSY;
1804 mutex_unlock(&s->open_mutex); 1813 if (file->f_flags & O_NONBLOCK)
1805 return -EBUSY; 1814 goto out;
1806 }
1807 add_wait_queue(&s->open_wait, &wait); 1815 add_wait_queue(&s->open_wait, &wait);
1808 __set_current_state(TASK_INTERRUPTIBLE); 1816 __set_current_state(TASK_INTERRUPTIBLE);
1809 mutex_unlock(&s->open_mutex); 1817 mutex_unlock(&s->open_mutex);
1810 schedule(); 1818 schedule();
1811 remove_wait_queue(&s->open_wait, &wait); 1819 remove_wait_queue(&s->open_wait, &wait);
1812 set_current_state(TASK_RUNNING); 1820 set_current_state(TASK_RUNNING);
1821 ret = -ERESTARTSYS;
1813 if (signal_pending(current)) 1822 if (signal_pending(current))
1814 return -ERESTARTSYS; 1823 goto out2;
1815 mutex_lock(&s->open_mutex); 1824 mutex_lock(&s->open_mutex);
1816 } 1825 }
1817 1826
@@ -1840,17 +1849,21 @@ au1550_open(struct inode *inode, struct file *file)
1840 1849
1841 if (file->f_mode & FMODE_READ) { 1850 if (file->f_mode & FMODE_READ) {
1842 if ((ret = prog_dmabuf_adc(s))) 1851 if ((ret = prog_dmabuf_adc(s)))
1843 return ret; 1852 goto out;
1844 } 1853 }
1845 if (file->f_mode & FMODE_WRITE) { 1854 if (file->f_mode & FMODE_WRITE) {
1846 if ((ret = prog_dmabuf_dac(s))) 1855 if ((ret = prog_dmabuf_dac(s)))
1847 return ret; 1856 goto out;
1848 } 1857 }
1849 1858
1850 s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); 1859 s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
1851 mutex_unlock(&s->open_mutex);
1852 mutex_init(&s->sem); 1860 mutex_init(&s->sem);
1853 return 0; 1861 ret = 0;
1862out:
1863 mutex_unlock(&s->open_mutex);
1864out2:
1865 unlock_kernel();
1866 return ret;
1854} 1867}
1855 1868
1856static int 1869static int
@@ -1885,15 +1898,15 @@ au1550_release(struct inode *inode, struct file *file)
1885} 1898}
1886 1899
1887static /*const */ struct file_operations au1550_audio_fops = { 1900static /*const */ struct file_operations au1550_audio_fops = {
1888 owner: THIS_MODULE, 1901 .owner = THIS_MODULE,
1889 llseek: au1550_llseek, 1902 .llseek = au1550_llseek,
1890 read: au1550_read, 1903 .read = au1550_read,
1891 write: au1550_write, 1904 .write = au1550_write,
1892 poll: au1550_poll, 1905 .poll = au1550_poll,
1893 ioctl: au1550_ioctl, 1906 .unlocked_ioctl = au1550_unlocked_ioctl,
1894 mmap: au1550_mmap, 1907 .mmap = au1550_mmap,
1895 open: au1550_open, 1908 .open = au1550_open,
1896 release: au1550_release, 1909 .release = au1550_release,
1897}; 1910};
1898 1911
1899MODULE_AUTHOR("Advanced Micro Devices (AMD), dan@embeddededge.com"); 1912MODULE_AUTHOR("Advanced Micro Devices (AMD), dan@embeddededge.com");