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