diff options
Diffstat (limited to 'sound/oss/sonicvibes.c')
| -rw-r--r-- | sound/oss/sonicvibes.c | 48 |
1 files changed, 25 insertions, 23 deletions
diff --git a/sound/oss/sonicvibes.c b/sound/oss/sonicvibes.c index 71b05e2f6977..69a4b8778b51 100644 --- a/sound/oss/sonicvibes.c +++ b/sound/oss/sonicvibes.c | |||
| @@ -116,6 +116,8 @@ | |||
| 116 | #include <linux/spinlock.h> | 116 | #include <linux/spinlock.h> |
| 117 | #include <linux/smp_lock.h> | 117 | #include <linux/smp_lock.h> |
| 118 | #include <linux/gameport.h> | 118 | #include <linux/gameport.h> |
| 119 | #include <linux/mutex.h> | ||
| 120 | |||
| 119 | 121 | ||
| 120 | #include <asm/io.h> | 122 | #include <asm/io.h> |
| 121 | #include <asm/uaccess.h> | 123 | #include <asm/uaccess.h> |
| @@ -328,7 +330,7 @@ struct sv_state { | |||
| 328 | unsigned char fmt, enable; | 330 | unsigned char fmt, enable; |
| 329 | 331 | ||
| 330 | spinlock_t lock; | 332 | spinlock_t lock; |
| 331 | struct semaphore open_sem; | 333 | struct mutex open_mutex; |
| 332 | mode_t open_mode; | 334 | mode_t open_mode; |
| 333 | wait_queue_head_t open_wait; | 335 | wait_queue_head_t open_wait; |
| 334 | 336 | ||
| @@ -1922,21 +1924,21 @@ static int sv_open(struct inode *inode, struct file *file) | |||
| 1922 | VALIDATE_STATE(s); | 1924 | VALIDATE_STATE(s); |
| 1923 | file->private_data = s; | 1925 | file->private_data = s; |
| 1924 | /* wait for device to become free */ | 1926 | /* wait for device to become free */ |
| 1925 | down(&s->open_sem); | 1927 | mutex_lock(&s->open_mutex); |
| 1926 | while (s->open_mode & file->f_mode) { | 1928 | while (s->open_mode & file->f_mode) { |
| 1927 | if (file->f_flags & O_NONBLOCK) { | 1929 | if (file->f_flags & O_NONBLOCK) { |
| 1928 | up(&s->open_sem); | 1930 | mutex_unlock(&s->open_mutex); |
| 1929 | return -EBUSY; | 1931 | return -EBUSY; |
| 1930 | } | 1932 | } |
| 1931 | add_wait_queue(&s->open_wait, &wait); | 1933 | add_wait_queue(&s->open_wait, &wait); |
| 1932 | __set_current_state(TASK_INTERRUPTIBLE); | 1934 | __set_current_state(TASK_INTERRUPTIBLE); |
| 1933 | up(&s->open_sem); | 1935 | mutex_unlock(&s->open_mutex); |
| 1934 | schedule(); | 1936 | schedule(); |
| 1935 | remove_wait_queue(&s->open_wait, &wait); | 1937 | remove_wait_queue(&s->open_wait, &wait); |
| 1936 | set_current_state(TASK_RUNNING); | 1938 | set_current_state(TASK_RUNNING); |
| 1937 | if (signal_pending(current)) | 1939 | if (signal_pending(current)) |
| 1938 | return -ERESTARTSYS; | 1940 | return -ERESTARTSYS; |
| 1939 | down(&s->open_sem); | 1941 | mutex_lock(&s->open_mutex); |
| 1940 | } | 1942 | } |
| 1941 | if (file->f_mode & FMODE_READ) { | 1943 | if (file->f_mode & FMODE_READ) { |
| 1942 | fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_CSHIFT); | 1944 | fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_CSHIFT); |
| @@ -1956,7 +1958,7 @@ static int sv_open(struct inode *inode, struct file *file) | |||
| 1956 | } | 1958 | } |
| 1957 | set_fmt(s, fmtm, fmts); | 1959 | set_fmt(s, fmtm, fmts); |
| 1958 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); | 1960 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); |
| 1959 | up(&s->open_sem); | 1961 | mutex_unlock(&s->open_mutex); |
| 1960 | return nonseekable_open(inode, file); | 1962 | return nonseekable_open(inode, file); |
| 1961 | } | 1963 | } |
| 1962 | 1964 | ||
| @@ -1968,7 +1970,7 @@ static int sv_release(struct inode *inode, struct file *file) | |||
| 1968 | lock_kernel(); | 1970 | lock_kernel(); |
| 1969 | if (file->f_mode & FMODE_WRITE) | 1971 | if (file->f_mode & FMODE_WRITE) |
| 1970 | drain_dac(s, file->f_flags & O_NONBLOCK); | 1972 | drain_dac(s, file->f_flags & O_NONBLOCK); |
| 1971 | down(&s->open_sem); | 1973 | mutex_lock(&s->open_mutex); |
| 1972 | if (file->f_mode & FMODE_WRITE) { | 1974 | if (file->f_mode & FMODE_WRITE) { |
| 1973 | stop_dac(s); | 1975 | stop_dac(s); |
| 1974 | dealloc_dmabuf(s, &s->dma_dac); | 1976 | dealloc_dmabuf(s, &s->dma_dac); |
| @@ -1979,7 +1981,7 @@ static int sv_release(struct inode *inode, struct file *file) | |||
| 1979 | } | 1981 | } |
| 1980 | s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE)); | 1982 | s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE)); |
| 1981 | wake_up(&s->open_wait); | 1983 | wake_up(&s->open_wait); |
| 1982 | up(&s->open_sem); | 1984 | mutex_unlock(&s->open_mutex); |
| 1983 | unlock_kernel(); | 1985 | unlock_kernel(); |
| 1984 | return 0; | 1986 | return 0; |
| 1985 | } | 1987 | } |
| @@ -2167,21 +2169,21 @@ static int sv_midi_open(struct inode *inode, struct file *file) | |||
| 2167 | VALIDATE_STATE(s); | 2169 | VALIDATE_STATE(s); |
| 2168 | file->private_data = s; | 2170 | file->private_data = s; |
| 2169 | /* wait for device to become free */ | 2171 | /* wait for device to become free */ |
| 2170 | down(&s->open_sem); | 2172 | mutex_lock(&s->open_mutex); |
| 2171 | while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { | 2173 | while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { |
| 2172 | if (file->f_flags & O_NONBLOCK) { | 2174 | if (file->f_flags & O_NONBLOCK) { |
| 2173 | up(&s->open_sem); | 2175 | mutex_unlock(&s->open_mutex); |
| 2174 | return -EBUSY; | 2176 | return -EBUSY; |
| 2175 | } | 2177 | } |
| 2176 | add_wait_queue(&s->open_wait, &wait); | 2178 | add_wait_queue(&s->open_wait, &wait); |
| 2177 | __set_current_state(TASK_INTERRUPTIBLE); | 2179 | __set_current_state(TASK_INTERRUPTIBLE); |
| 2178 | up(&s->open_sem); | 2180 | mutex_unlock(&s->open_mutex); |
| 2179 | schedule(); | 2181 | schedule(); |
| 2180 | remove_wait_queue(&s->open_wait, &wait); | 2182 | remove_wait_queue(&s->open_wait, &wait); |
| 2181 | set_current_state(TASK_RUNNING); | 2183 | set_current_state(TASK_RUNNING); |
| 2182 | if (signal_pending(current)) | 2184 | if (signal_pending(current)) |
| 2183 | return -ERESTARTSYS; | 2185 | return -ERESTARTSYS; |
| 2184 | down(&s->open_sem); | 2186 | mutex_lock(&s->open_mutex); |
| 2185 | } | 2187 | } |
| 2186 | spin_lock_irqsave(&s->lock, flags); | 2188 | spin_lock_irqsave(&s->lock, flags); |
| 2187 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { | 2189 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { |
| @@ -2210,7 +2212,7 @@ static int sv_midi_open(struct inode *inode, struct file *file) | |||
| 2210 | } | 2212 | } |
| 2211 | spin_unlock_irqrestore(&s->lock, flags); | 2213 | spin_unlock_irqrestore(&s->lock, flags); |
| 2212 | s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); | 2214 | s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); |
| 2213 | up(&s->open_sem); | 2215 | mutex_unlock(&s->open_mutex); |
| 2214 | return nonseekable_open(inode, file); | 2216 | return nonseekable_open(inode, file); |
| 2215 | } | 2217 | } |
| 2216 | 2218 | ||
| @@ -2248,7 +2250,7 @@ static int sv_midi_release(struct inode *inode, struct file *file) | |||
| 2248 | remove_wait_queue(&s->midi.owait, &wait); | 2250 | remove_wait_queue(&s->midi.owait, &wait); |
| 2249 | set_current_state(TASK_RUNNING); | 2251 | set_current_state(TASK_RUNNING); |
| 2250 | } | 2252 | } |
| 2251 | down(&s->open_sem); | 2253 | mutex_lock(&s->open_mutex); |
| 2252 | s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE)); | 2254 | s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE)); |
| 2253 | spin_lock_irqsave(&s->lock, flags); | 2255 | spin_lock_irqsave(&s->lock, flags); |
| 2254 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { | 2256 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { |
| @@ -2257,7 +2259,7 @@ static int sv_midi_release(struct inode *inode, struct file *file) | |||
| 2257 | } | 2259 | } |
| 2258 | spin_unlock_irqrestore(&s->lock, flags); | 2260 | spin_unlock_irqrestore(&s->lock, flags); |
| 2259 | wake_up(&s->open_wait); | 2261 | wake_up(&s->open_wait); |
| 2260 | up(&s->open_sem); | 2262 | mutex_unlock(&s->open_mutex); |
| 2261 | unlock_kernel(); | 2263 | unlock_kernel(); |
| 2262 | return 0; | 2264 | return 0; |
| 2263 | } | 2265 | } |
| @@ -2388,21 +2390,21 @@ static int sv_dmfm_open(struct inode *inode, struct file *file) | |||
| 2388 | VALIDATE_STATE(s); | 2390 | VALIDATE_STATE(s); |
| 2389 | file->private_data = s; | 2391 | file->private_data = s; |
| 2390 | /* wait for device to become free */ | 2392 | /* wait for device to become free */ |
| 2391 | down(&s->open_sem); | 2393 | mutex_lock(&s->open_mutex); |
| 2392 | while (s->open_mode & FMODE_DMFM) { | 2394 | while (s->open_mode & FMODE_DMFM) { |
| 2393 | if (file->f_flags & O_NONBLOCK) { | 2395 | if (file->f_flags & O_NONBLOCK) { |
| 2394 | up(&s->open_sem); | 2396 | mutex_unlock(&s->open_mutex); |
| 2395 | return -EBUSY; | 2397 | return -EBUSY; |
| 2396 | } | 2398 | } |
| 2397 | add_wait_queue(&s->open_wait, &wait); | 2399 | add_wait_queue(&s->open_wait, &wait); |
| 2398 | __set_current_state(TASK_INTERRUPTIBLE); | 2400 | __set_current_state(TASK_INTERRUPTIBLE); |
| 2399 | up(&s->open_sem); | 2401 | mutex_unlock(&s->open_mutex); |
| 2400 | schedule(); | 2402 | schedule(); |
| 2401 | remove_wait_queue(&s->open_wait, &wait); | 2403 | remove_wait_queue(&s->open_wait, &wait); |
| 2402 | set_current_state(TASK_RUNNING); | 2404 | set_current_state(TASK_RUNNING); |
| 2403 | if (signal_pending(current)) | 2405 | if (signal_pending(current)) |
| 2404 | return -ERESTARTSYS; | 2406 | return -ERESTARTSYS; |
| 2405 | down(&s->open_sem); | 2407 | mutex_lock(&s->open_mutex); |
| 2406 | } | 2408 | } |
| 2407 | /* init the stuff */ | 2409 | /* init the stuff */ |
| 2408 | outb(1, s->iosynth); | 2410 | outb(1, s->iosynth); |
| @@ -2412,7 +2414,7 @@ static int sv_dmfm_open(struct inode *inode, struct file *file) | |||
| 2412 | outb(5, s->iosynth+2); | 2414 | outb(5, s->iosynth+2); |
| 2413 | outb(1, s->iosynth+3); /* enable OPL3 */ | 2415 | outb(1, s->iosynth+3); /* enable OPL3 */ |
| 2414 | s->open_mode |= FMODE_DMFM; | 2416 | s->open_mode |= FMODE_DMFM; |
| 2415 | up(&s->open_sem); | 2417 | mutex_unlock(&s->open_mutex); |
| 2416 | return nonseekable_open(inode, file); | 2418 | return nonseekable_open(inode, file); |
| 2417 | } | 2419 | } |
| 2418 | 2420 | ||
| @@ -2423,7 +2425,7 @@ static int sv_dmfm_release(struct inode *inode, struct file *file) | |||
| 2423 | 2425 | ||
| 2424 | VALIDATE_STATE(s); | 2426 | VALIDATE_STATE(s); |
| 2425 | lock_kernel(); | 2427 | lock_kernel(); |
| 2426 | down(&s->open_sem); | 2428 | mutex_lock(&s->open_mutex); |
| 2427 | s->open_mode &= ~FMODE_DMFM; | 2429 | s->open_mode &= ~FMODE_DMFM; |
| 2428 | for (regb = 0xb0; regb < 0xb9; regb++) { | 2430 | for (regb = 0xb0; regb < 0xb9; regb++) { |
| 2429 | outb(regb, s->iosynth); | 2431 | outb(regb, s->iosynth); |
| @@ -2432,7 +2434,7 @@ static int sv_dmfm_release(struct inode *inode, struct file *file) | |||
| 2432 | outb(0, s->iosynth+3); | 2434 | outb(0, s->iosynth+3); |
| 2433 | } | 2435 | } |
| 2434 | wake_up(&s->open_wait); | 2436 | wake_up(&s->open_wait); |
| 2435 | up(&s->open_sem); | 2437 | mutex_unlock(&s->open_mutex); |
| 2436 | unlock_kernel(); | 2438 | unlock_kernel(); |
| 2437 | return 0; | 2439 | return 0; |
| 2438 | } | 2440 | } |
| @@ -2582,7 +2584,7 @@ static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id | |||
| 2582 | init_waitqueue_head(&s->open_wait); | 2584 | init_waitqueue_head(&s->open_wait); |
| 2583 | init_waitqueue_head(&s->midi.iwait); | 2585 | init_waitqueue_head(&s->midi.iwait); |
| 2584 | init_waitqueue_head(&s->midi.owait); | 2586 | init_waitqueue_head(&s->midi.owait); |
| 2585 | init_MUTEX(&s->open_sem); | 2587 | mutex_init(&s->open_mutex); |
| 2586 | spin_lock_init(&s->lock); | 2588 | spin_lock_init(&s->lock); |
| 2587 | s->magic = SV_MAGIC; | 2589 | s->magic = SV_MAGIC; |
| 2588 | s->dev = pcidev; | 2590 | s->dev = pcidev; |
