diff options
Diffstat (limited to 'sound/oss/esssolo1.c')
-rw-r--r-- | sound/oss/esssolo1.c | 50 |
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; |