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; |
