aboutsummaryrefslogtreecommitdiffstats
path: root/sound/oss/esssolo1.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/oss/esssolo1.c')
-rw-r--r--sound/oss/esssolo1.c50
1 files changed, 26 insertions, 24 deletions
diff --git a/sound/oss/esssolo1.c b/sound/oss/esssolo1.c
index 849b59f67ef5..78d3e29ce968 100644
--- a/sound/oss/esssolo1.c
+++ b/sound/oss/esssolo1.c
@@ -105,6 +105,8 @@
105#include <linux/gameport.h> 105#include <linux/gameport.h>
106#include <linux/wait.h> 106#include <linux/wait.h>
107#include <linux/dma-mapping.h> 107#include <linux/dma-mapping.h>
108#include <linux/mutex.h>
109
108 110
109#include <asm/io.h> 111#include <asm/io.h>
110#include <asm/page.h> 112#include <asm/page.h>
@@ -191,7 +193,7 @@ struct solo1_state {
191 unsigned ena; 193 unsigned ena;
192 194
193 spinlock_t lock; 195 spinlock_t lock;
194 struct semaphore open_sem; 196 struct mutex open_mutex;
195 mode_t open_mode; 197 mode_t open_mode;
196 wait_queue_head_t open_wait; 198 wait_queue_head_t open_wait;
197 199
@@ -1581,7 +1583,7 @@ static int solo1_release(struct inode *inode, struct file *file)
1581 lock_kernel(); 1583 lock_kernel();
1582 if (file->f_mode & FMODE_WRITE) 1584 if (file->f_mode & FMODE_WRITE)
1583 drain_dac(s, file->f_flags & O_NONBLOCK); 1585 drain_dac(s, file->f_flags & O_NONBLOCK);
1584 down(&s->open_sem); 1586 mutex_lock(&s->open_mutex);
1585 if (file->f_mode & FMODE_WRITE) { 1587 if (file->f_mode & FMODE_WRITE) {
1586 stop_dac(s); 1588 stop_dac(s);
1587 outb(0, s->iobase+6); /* disable DMA */ 1589 outb(0, s->iobase+6); /* disable DMA */
@@ -1595,7 +1597,7 @@ static int solo1_release(struct inode *inode, struct file *file)
1595 } 1597 }
1596 s->open_mode &= ~(FMODE_READ | FMODE_WRITE); 1598 s->open_mode &= ~(FMODE_READ | FMODE_WRITE);
1597 wake_up(&s->open_wait); 1599 wake_up(&s->open_wait);
1598 up(&s->open_sem); 1600 mutex_unlock(&s->open_mutex);
1599 unlock_kernel(); 1601 unlock_kernel();
1600 return 0; 1602 return 0;
1601} 1603}
@@ -1624,21 +1626,21 @@ static int solo1_open(struct inode *inode, struct file *file)
1624 VALIDATE_STATE(s); 1626 VALIDATE_STATE(s);
1625 file->private_data = s; 1627 file->private_data = s;
1626 /* wait for device to become free */ 1628 /* wait for device to become free */
1627 down(&s->open_sem); 1629 mutex_lock(&s->open_mutex);
1628 while (s->open_mode & (FMODE_READ | FMODE_WRITE)) { 1630 while (s->open_mode & (FMODE_READ | FMODE_WRITE)) {
1629 if (file->f_flags & O_NONBLOCK) { 1631 if (file->f_flags & O_NONBLOCK) {
1630 up(&s->open_sem); 1632 mutex_unlock(&s->open_mutex);
1631 return -EBUSY; 1633 return -EBUSY;
1632 } 1634 }
1633 add_wait_queue(&s->open_wait, &wait); 1635 add_wait_queue(&s->open_wait, &wait);
1634 __set_current_state(TASK_INTERRUPTIBLE); 1636 __set_current_state(TASK_INTERRUPTIBLE);
1635 up(&s->open_sem); 1637 mutex_unlock(&s->open_mutex);
1636 schedule(); 1638 schedule();
1637 remove_wait_queue(&s->open_wait, &wait); 1639 remove_wait_queue(&s->open_wait, &wait);
1638 set_current_state(TASK_RUNNING); 1640 set_current_state(TASK_RUNNING);
1639 if (signal_pending(current)) 1641 if (signal_pending(current))
1640 return -ERESTARTSYS; 1642 return -ERESTARTSYS;
1641 down(&s->open_sem); 1643 mutex_lock(&s->open_mutex);
1642 } 1644 }
1643 s->fmt = AFMT_U8; 1645 s->fmt = AFMT_U8;
1644 s->channels = 1; 1646 s->channels = 1;
@@ -1650,7 +1652,7 @@ static int solo1_open(struct inode *inode, struct file *file)
1650 s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0; 1652 s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
1651 s->dma_dac.enabled = 1; 1653 s->dma_dac.enabled = 1;
1652 s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); 1654 s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
1653 up(&s->open_sem); 1655 mutex_unlock(&s->open_mutex);
1654 prog_codec(s); 1656 prog_codec(s);
1655 return nonseekable_open(inode, file); 1657 return nonseekable_open(inode, file);
1656} 1658}
@@ -1911,21 +1913,21 @@ static int solo1_midi_open(struct inode *inode, struct file *file)
1911 VALIDATE_STATE(s); 1913 VALIDATE_STATE(s);
1912 file->private_data = s; 1914 file->private_data = s;
1913 /* wait for device to become free */ 1915 /* wait for device to become free */
1914 down(&s->open_sem); 1916 mutex_lock(&s->open_mutex);
1915 while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { 1917 while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
1916 if (file->f_flags & O_NONBLOCK) { 1918 if (file->f_flags & O_NONBLOCK) {
1917 up(&s->open_sem); 1919 mutex_unlock(&s->open_mutex);
1918 return -EBUSY; 1920 return -EBUSY;
1919 } 1921 }
1920 add_wait_queue(&s->open_wait, &wait); 1922 add_wait_queue(&s->open_wait, &wait);
1921 __set_current_state(TASK_INTERRUPTIBLE); 1923 __set_current_state(TASK_INTERRUPTIBLE);
1922 up(&s->open_sem); 1924 mutex_unlock(&s->open_mutex);
1923 schedule(); 1925 schedule();
1924 remove_wait_queue(&s->open_wait, &wait); 1926 remove_wait_queue(&s->open_wait, &wait);
1925 set_current_state(TASK_RUNNING); 1927 set_current_state(TASK_RUNNING);
1926 if (signal_pending(current)) 1928 if (signal_pending(current))
1927 return -ERESTARTSYS; 1929 return -ERESTARTSYS;
1928 down(&s->open_sem); 1930 mutex_lock(&s->open_mutex);
1929 } 1931 }
1930 spin_lock_irqsave(&s->lock, flags); 1932 spin_lock_irqsave(&s->lock, flags);
1931 if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { 1933 if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
@@ -1951,7 +1953,7 @@ static int solo1_midi_open(struct inode *inode, struct file *file)
1951 } 1953 }
1952 spin_unlock_irqrestore(&s->lock, flags); 1954 spin_unlock_irqrestore(&s->lock, flags);
1953 s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); 1955 s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
1954 up(&s->open_sem); 1956 mutex_unlock(&s->open_mutex);
1955 return nonseekable_open(inode, file); 1957 return nonseekable_open(inode, file);
1956} 1958}
1957 1959
@@ -1985,7 +1987,7 @@ static int solo1_midi_release(struct inode *inode, struct file *file)
1985 remove_wait_queue(&s->midi.owait, &wait); 1987 remove_wait_queue(&s->midi.owait, &wait);
1986 set_current_state(TASK_RUNNING); 1988 set_current_state(TASK_RUNNING);
1987 } 1989 }
1988 down(&s->open_sem); 1990 mutex_lock(&s->open_mutex);
1989 s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE)); 1991 s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
1990 spin_lock_irqsave(&s->lock, flags); 1992 spin_lock_irqsave(&s->lock, flags);
1991 if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { 1993 if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
@@ -1994,7 +1996,7 @@ static int solo1_midi_release(struct inode *inode, struct file *file)
1994 } 1996 }
1995 spin_unlock_irqrestore(&s->lock, flags); 1997 spin_unlock_irqrestore(&s->lock, flags);
1996 wake_up(&s->open_wait); 1998 wake_up(&s->open_wait);
1997 up(&s->open_sem); 1999 mutex_unlock(&s->open_mutex);
1998 unlock_kernel(); 2000 unlock_kernel();
1999 return 0; 2001 return 0;
2000} 2002}
@@ -2132,24 +2134,24 @@ static int solo1_dmfm_open(struct inode *inode, struct file *file)
2132 VALIDATE_STATE(s); 2134 VALIDATE_STATE(s);
2133 file->private_data = s; 2135 file->private_data = s;
2134 /* wait for device to become free */ 2136 /* wait for device to become free */
2135 down(&s->open_sem); 2137 mutex_lock(&s->open_mutex);
2136 while (s->open_mode & FMODE_DMFM) { 2138 while (s->open_mode & FMODE_DMFM) {
2137 if (file->f_flags & O_NONBLOCK) { 2139 if (file->f_flags & O_NONBLOCK) {
2138 up(&s->open_sem); 2140 mutex_unlock(&s->open_mutex);
2139 return -EBUSY; 2141 return -EBUSY;
2140 } 2142 }
2141 add_wait_queue(&s->open_wait, &wait); 2143 add_wait_queue(&s->open_wait, &wait);
2142 __set_current_state(TASK_INTERRUPTIBLE); 2144 __set_current_state(TASK_INTERRUPTIBLE);
2143 up(&s->open_sem); 2145 mutex_unlock(&s->open_mutex);
2144 schedule(); 2146 schedule();
2145 remove_wait_queue(&s->open_wait, &wait); 2147 remove_wait_queue(&s->open_wait, &wait);
2146 set_current_state(TASK_RUNNING); 2148 set_current_state(TASK_RUNNING);
2147 if (signal_pending(current)) 2149 if (signal_pending(current))
2148 return -ERESTARTSYS; 2150 return -ERESTARTSYS;
2149 down(&s->open_sem); 2151 mutex_lock(&s->open_mutex);
2150 } 2152 }
2151 if (!request_region(s->sbbase, FMSYNTH_EXTENT, "ESS Solo1")) { 2153 if (!request_region(s->sbbase, FMSYNTH_EXTENT, "ESS Solo1")) {
2152 up(&s->open_sem); 2154 mutex_unlock(&s->open_mutex);
2153 printk(KERN_ERR "solo1: FM synth io ports in use, opl3 loaded?\n"); 2155 printk(KERN_ERR "solo1: FM synth io ports in use, opl3 loaded?\n");
2154 return -EBUSY; 2156 return -EBUSY;
2155 } 2157 }
@@ -2161,7 +2163,7 @@ static int solo1_dmfm_open(struct inode *inode, struct file *file)
2161 outb(5, s->sbbase+2); 2163 outb(5, s->sbbase+2);
2162 outb(1, s->sbbase+3); /* enable OPL3 */ 2164 outb(1, s->sbbase+3); /* enable OPL3 */
2163 s->open_mode |= FMODE_DMFM; 2165 s->open_mode |= FMODE_DMFM;
2164 up(&s->open_sem); 2166 mutex_unlock(&s->open_mutex);
2165 return nonseekable_open(inode, file); 2167 return nonseekable_open(inode, file);
2166} 2168}
2167 2169
@@ -2172,7 +2174,7 @@ static int solo1_dmfm_release(struct inode *inode, struct file *file)
2172 2174
2173 VALIDATE_STATE(s); 2175 VALIDATE_STATE(s);
2174 lock_kernel(); 2176 lock_kernel();
2175 down(&s->open_sem); 2177 mutex_lock(&s->open_mutex);
2176 s->open_mode &= ~FMODE_DMFM; 2178 s->open_mode &= ~FMODE_DMFM;
2177 for (regb = 0xb0; regb < 0xb9; regb++) { 2179 for (regb = 0xb0; regb < 0xb9; regb++) {
2178 outb(regb, s->sbbase); 2180 outb(regb, s->sbbase);
@@ -2182,7 +2184,7 @@ static int solo1_dmfm_release(struct inode *inode, struct file *file)
2182 } 2184 }
2183 release_region(s->sbbase, FMSYNTH_EXTENT); 2185 release_region(s->sbbase, FMSYNTH_EXTENT);
2184 wake_up(&s->open_wait); 2186 wake_up(&s->open_wait);
2185 up(&s->open_sem); 2187 mutex_unlock(&s->open_mutex);
2186 unlock_kernel(); 2188 unlock_kernel();
2187 return 0; 2189 return 0;
2188} 2190}
@@ -2362,7 +2364,7 @@ static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device
2362 init_waitqueue_head(&s->open_wait); 2364 init_waitqueue_head(&s->open_wait);
2363 init_waitqueue_head(&s->midi.iwait); 2365 init_waitqueue_head(&s->midi.iwait);
2364 init_waitqueue_head(&s->midi.owait); 2366 init_waitqueue_head(&s->midi.owait);
2365 init_MUTEX(&s->open_sem); 2367 mutex_init(&s->open_mutex);
2366 spin_lock_init(&s->lock); 2368 spin_lock_init(&s->lock);
2367 s->magic = SOLO1_MAGIC; 2369 s->magic = SOLO1_MAGIC;
2368 s->dev = pcidev; 2370 s->dev = pcidev;