diff options
Diffstat (limited to 'sound/oss/cs46xx.c')
-rw-r--r-- | sound/oss/cs46xx.c | 75 |
1 files changed, 38 insertions, 37 deletions
diff --git a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c index 58e25c82eaf2..53881bc91bba 100644 --- a/sound/oss/cs46xx.c +++ b/sound/oss/cs46xx.c | |||
@@ -90,6 +90,7 @@ | |||
90 | #include <linux/init.h> | 90 | #include <linux/init.h> |
91 | #include <linux/poll.h> | 91 | #include <linux/poll.h> |
92 | #include <linux/ac97_codec.h> | 92 | #include <linux/ac97_codec.h> |
93 | #include <linux/mutex.h> | ||
93 | 94 | ||
94 | #include <asm/io.h> | 95 | #include <asm/io.h> |
95 | #include <asm/dma.h> | 96 | #include <asm/dma.h> |
@@ -238,7 +239,7 @@ struct cs_state { | |||
238 | struct cs_card *card; /* Card info */ | 239 | struct cs_card *card; /* Card info */ |
239 | 240 | ||
240 | /* single open lock mechanism, only used for recording */ | 241 | /* single open lock mechanism, only used for recording */ |
241 | struct semaphore open_sem; | 242 | struct mutex open_mutex; |
242 | wait_queue_head_t open_wait; | 243 | wait_queue_head_t open_wait; |
243 | 244 | ||
244 | /* file mode */ | 245 | /* file mode */ |
@@ -297,7 +298,7 @@ struct cs_state { | |||
297 | unsigned subdivision; | 298 | unsigned subdivision; |
298 | } dmabuf; | 299 | } dmabuf; |
299 | /* Guard against mmap/write/read races */ | 300 | /* Guard against mmap/write/read races */ |
300 | struct semaphore sem; | 301 | struct mutex sem; |
301 | }; | 302 | }; |
302 | 303 | ||
303 | struct cs_card { | 304 | struct cs_card { |
@@ -375,7 +376,7 @@ struct cs_card { | |||
375 | unsigned char ibuf[CS_MIDIINBUF]; | 376 | unsigned char ibuf[CS_MIDIINBUF]; |
376 | unsigned char obuf[CS_MIDIOUTBUF]; | 377 | unsigned char obuf[CS_MIDIOUTBUF]; |
377 | mode_t open_mode; | 378 | mode_t open_mode; |
378 | struct semaphore open_sem; | 379 | struct mutex open_mutex; |
379 | } midi; | 380 | } midi; |
380 | struct cs46xx_pm pm; | 381 | struct cs46xx_pm pm; |
381 | }; | 382 | }; |
@@ -1428,9 +1429,9 @@ static int prog_dmabuf(struct cs_state *state) | |||
1428 | { | 1429 | { |
1429 | int ret; | 1430 | int ret; |
1430 | 1431 | ||
1431 | down(&state->sem); | 1432 | mutex_lock(&state->sem); |
1432 | ret = __prog_dmabuf(state); | 1433 | ret = __prog_dmabuf(state); |
1433 | up(&state->sem); | 1434 | mutex_unlock(&state->sem); |
1434 | 1435 | ||
1435 | return ret; | 1436 | return ret; |
1436 | } | 1437 | } |
@@ -1831,17 +1832,17 @@ static int cs_midi_open(struct inode *inode, struct file *file) | |||
1831 | 1832 | ||
1832 | file->private_data = card; | 1833 | file->private_data = card; |
1833 | /* wait for device to become free */ | 1834 | /* wait for device to become free */ |
1834 | down(&card->midi.open_sem); | 1835 | mutex_lock(&card->midi.open_mutex); |
1835 | while (card->midi.open_mode & file->f_mode) { | 1836 | while (card->midi.open_mode & file->f_mode) { |
1836 | if (file->f_flags & O_NONBLOCK) { | 1837 | if (file->f_flags & O_NONBLOCK) { |
1837 | up(&card->midi.open_sem); | 1838 | mutex_unlock(&card->midi.open_mutex); |
1838 | return -EBUSY; | 1839 | return -EBUSY; |
1839 | } | 1840 | } |
1840 | up(&card->midi.open_sem); | 1841 | mutex_unlock(&card->midi.open_mutex); |
1841 | interruptible_sleep_on(&card->midi.open_wait); | 1842 | interruptible_sleep_on(&card->midi.open_wait); |
1842 | if (signal_pending(current)) | 1843 | if (signal_pending(current)) |
1843 | return -ERESTARTSYS; | 1844 | return -ERESTARTSYS; |
1844 | down(&card->midi.open_sem); | 1845 | mutex_lock(&card->midi.open_mutex); |
1845 | } | 1846 | } |
1846 | spin_lock_irqsave(&card->midi.lock, flags); | 1847 | spin_lock_irqsave(&card->midi.lock, flags); |
1847 | if (!(card->midi.open_mode & (FMODE_READ | FMODE_WRITE))) { | 1848 | if (!(card->midi.open_mode & (FMODE_READ | FMODE_WRITE))) { |
@@ -1859,7 +1860,7 @@ static int cs_midi_open(struct inode *inode, struct file *file) | |||
1859 | } | 1860 | } |
1860 | spin_unlock_irqrestore(&card->midi.lock, flags); | 1861 | spin_unlock_irqrestore(&card->midi.lock, flags); |
1861 | card->midi.open_mode |= (file->f_mode & (FMODE_READ | FMODE_WRITE)); | 1862 | card->midi.open_mode |= (file->f_mode & (FMODE_READ | FMODE_WRITE)); |
1862 | up(&card->midi.open_sem); | 1863 | mutex_unlock(&card->midi.open_mutex); |
1863 | return 0; | 1864 | return 0; |
1864 | } | 1865 | } |
1865 | 1866 | ||
@@ -1891,9 +1892,9 @@ static int cs_midi_release(struct inode *inode, struct file *file) | |||
1891 | remove_wait_queue(&card->midi.owait, &wait); | 1892 | remove_wait_queue(&card->midi.owait, &wait); |
1892 | current->state = TASK_RUNNING; | 1893 | current->state = TASK_RUNNING; |
1893 | } | 1894 | } |
1894 | down(&card->midi.open_sem); | 1895 | mutex_lock(&card->midi.open_mutex); |
1895 | card->midi.open_mode &= (~(file->f_mode & (FMODE_READ | FMODE_WRITE))); | 1896 | card->midi.open_mode &= (~(file->f_mode & (FMODE_READ | FMODE_WRITE))); |
1896 | up(&card->midi.open_sem); | 1897 | mutex_unlock(&card->midi.open_mutex); |
1897 | wake_up(&card->midi.open_wait); | 1898 | wake_up(&card->midi.open_wait); |
1898 | return 0; | 1899 | return 0; |
1899 | } | 1900 | } |
@@ -2081,7 +2082,7 @@ static ssize_t cs_read(struct file *file, char __user *buffer, size_t count, lof | |||
2081 | if (!access_ok(VERIFY_WRITE, buffer, count)) | 2082 | if (!access_ok(VERIFY_WRITE, buffer, count)) |
2082 | return -EFAULT; | 2083 | return -EFAULT; |
2083 | 2084 | ||
2084 | down(&state->sem); | 2085 | mutex_lock(&state->sem); |
2085 | if (!dmabuf->ready && (ret = __prog_dmabuf(state))) | 2086 | if (!dmabuf->ready && (ret = __prog_dmabuf(state))) |
2086 | goto out2; | 2087 | goto out2; |
2087 | 2088 | ||
@@ -2114,13 +2115,13 @@ static ssize_t cs_read(struct file *file, char __user *buffer, size_t count, lof | |||
2114 | if (!ret) ret = -EAGAIN; | 2115 | if (!ret) ret = -EAGAIN; |
2115 | goto out; | 2116 | goto out; |
2116 | } | 2117 | } |
2117 | up(&state->sem); | 2118 | mutex_unlock(&state->sem); |
2118 | schedule(); | 2119 | schedule(); |
2119 | if (signal_pending(current)) { | 2120 | if (signal_pending(current)) { |
2120 | if(!ret) ret = -ERESTARTSYS; | 2121 | if(!ret) ret = -ERESTARTSYS; |
2121 | goto out; | 2122 | goto out; |
2122 | } | 2123 | } |
2123 | down(&state->sem); | 2124 | mutex_lock(&state->sem); |
2124 | if (dmabuf->mapped) | 2125 | if (dmabuf->mapped) |
2125 | { | 2126 | { |
2126 | if(!ret) | 2127 | if(!ret) |
@@ -2155,7 +2156,7 @@ static ssize_t cs_read(struct file *file, char __user *buffer, size_t count, lof | |||
2155 | out: | 2156 | out: |
2156 | remove_wait_queue(&state->dmabuf.wait, &wait); | 2157 | remove_wait_queue(&state->dmabuf.wait, &wait); |
2157 | out2: | 2158 | out2: |
2158 | up(&state->sem); | 2159 | mutex_unlock(&state->sem); |
2159 | set_current_state(TASK_RUNNING); | 2160 | set_current_state(TASK_RUNNING); |
2160 | CS_DBGOUT(CS_WAVE_READ | CS_FUNCTION, 4, | 2161 | CS_DBGOUT(CS_WAVE_READ | CS_FUNCTION, 4, |
2161 | printk("cs46xx: cs_read()- %zd\n",ret) ); | 2162 | printk("cs46xx: cs_read()- %zd\n",ret) ); |
@@ -2184,7 +2185,7 @@ static ssize_t cs_write(struct file *file, const char __user *buffer, size_t cou | |||
2184 | return -EFAULT; | 2185 | return -EFAULT; |
2185 | dmabuf = &state->dmabuf; | 2186 | dmabuf = &state->dmabuf; |
2186 | 2187 | ||
2187 | down(&state->sem); | 2188 | mutex_lock(&state->sem); |
2188 | if (dmabuf->mapped) | 2189 | if (dmabuf->mapped) |
2189 | { | 2190 | { |
2190 | ret = -ENXIO; | 2191 | ret = -ENXIO; |
@@ -2240,13 +2241,13 @@ static ssize_t cs_write(struct file *file, const char __user *buffer, size_t cou | |||
2240 | if (!ret) ret = -EAGAIN; | 2241 | if (!ret) ret = -EAGAIN; |
2241 | goto out; | 2242 | goto out; |
2242 | } | 2243 | } |
2243 | up(&state->sem); | 2244 | mutex_unlock(&state->sem); |
2244 | schedule(); | 2245 | schedule(); |
2245 | if (signal_pending(current)) { | 2246 | if (signal_pending(current)) { |
2246 | if(!ret) ret = -ERESTARTSYS; | 2247 | if(!ret) ret = -ERESTARTSYS; |
2247 | goto out; | 2248 | goto out; |
2248 | } | 2249 | } |
2249 | down(&state->sem); | 2250 | mutex_lock(&state->sem); |
2250 | if (dmabuf->mapped) | 2251 | if (dmabuf->mapped) |
2251 | { | 2252 | { |
2252 | if(!ret) | 2253 | if(!ret) |
@@ -2278,7 +2279,7 @@ static ssize_t cs_write(struct file *file, const char __user *buffer, size_t cou | |||
2278 | start_dac(state); | 2279 | start_dac(state); |
2279 | } | 2280 | } |
2280 | out: | 2281 | out: |
2281 | up(&state->sem); | 2282 | mutex_unlock(&state->sem); |
2282 | remove_wait_queue(&state->dmabuf.wait, &wait); | 2283 | remove_wait_queue(&state->dmabuf.wait, &wait); |
2283 | set_current_state(TASK_RUNNING); | 2284 | set_current_state(TASK_RUNNING); |
2284 | 2285 | ||
@@ -2411,7 +2412,7 @@ static int cs_mmap(struct file *file, struct vm_area_struct *vma) | |||
2411 | goto out; | 2412 | goto out; |
2412 | } | 2413 | } |
2413 | 2414 | ||
2414 | down(&state->sem); | 2415 | mutex_lock(&state->sem); |
2415 | dmabuf = &state->dmabuf; | 2416 | dmabuf = &state->dmabuf; |
2416 | if (cs4x_pgoff(vma) != 0) | 2417 | if (cs4x_pgoff(vma) != 0) |
2417 | { | 2418 | { |
@@ -2438,7 +2439,7 @@ static int cs_mmap(struct file *file, struct vm_area_struct *vma) | |||
2438 | 2439 | ||
2439 | CS_DBGOUT(CS_FUNCTION, 2, printk("cs46xx: cs_mmap()-\n") ); | 2440 | CS_DBGOUT(CS_FUNCTION, 2, printk("cs46xx: cs_mmap()-\n") ); |
2440 | out: | 2441 | out: |
2441 | up(&state->sem); | 2442 | mutex_unlock(&state->sem); |
2442 | return ret; | 2443 | return ret; |
2443 | } | 2444 | } |
2444 | 2445 | ||
@@ -3200,7 +3201,7 @@ static int cs_open(struct inode *inode, struct file *file) | |||
3200 | if (state == NULL) | 3201 | if (state == NULL) |
3201 | return -ENOMEM; | 3202 | return -ENOMEM; |
3202 | memset(state, 0, sizeof(struct cs_state)); | 3203 | memset(state, 0, sizeof(struct cs_state)); |
3203 | init_MUTEX(&state->sem); | 3204 | mutex_init(&state->sem); |
3204 | dmabuf = &state->dmabuf; | 3205 | dmabuf = &state->dmabuf; |
3205 | dmabuf->pbuf = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); | 3206 | dmabuf->pbuf = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); |
3206 | if(dmabuf->pbuf==NULL) | 3207 | if(dmabuf->pbuf==NULL) |
@@ -3241,10 +3242,10 @@ static int cs_open(struct inode *inode, struct file *file) | |||
3241 | state->virt = 0; | 3242 | state->virt = 0; |
3242 | state->magic = CS_STATE_MAGIC; | 3243 | state->magic = CS_STATE_MAGIC; |
3243 | init_waitqueue_head(&dmabuf->wait); | 3244 | init_waitqueue_head(&dmabuf->wait); |
3244 | init_MUTEX(&state->open_sem); | 3245 | mutex_init(&state->open_mutex); |
3245 | file->private_data = card; | 3246 | file->private_data = card; |
3246 | 3247 | ||
3247 | down(&state->open_sem); | 3248 | mutex_lock(&state->open_mutex); |
3248 | 3249 | ||
3249 | /* set default sample format. According to OSS Programmer's Guide /dev/dsp | 3250 | /* set default sample format. According to OSS Programmer's Guide /dev/dsp |
3250 | should be default to unsigned 8-bits, mono, with sample rate 8kHz and | 3251 | should be default to unsigned 8-bits, mono, with sample rate 8kHz and |
@@ -3260,7 +3261,7 @@ static int cs_open(struct inode *inode, struct file *file) | |||
3260 | cs_set_divisor(dmabuf); | 3261 | cs_set_divisor(dmabuf); |
3261 | 3262 | ||
3262 | state->open_mode |= FMODE_READ; | 3263 | state->open_mode |= FMODE_READ; |
3263 | up(&state->open_sem); | 3264 | mutex_unlock(&state->open_mutex); |
3264 | } | 3265 | } |
3265 | if(file->f_mode & FMODE_WRITE) | 3266 | if(file->f_mode & FMODE_WRITE) |
3266 | { | 3267 | { |
@@ -3271,7 +3272,7 @@ static int cs_open(struct inode *inode, struct file *file) | |||
3271 | if (state == NULL) | 3272 | if (state == NULL) |
3272 | return -ENOMEM; | 3273 | return -ENOMEM; |
3273 | memset(state, 0, sizeof(struct cs_state)); | 3274 | memset(state, 0, sizeof(struct cs_state)); |
3274 | init_MUTEX(&state->sem); | 3275 | mutex_init(&state->sem); |
3275 | dmabuf = &state->dmabuf; | 3276 | dmabuf = &state->dmabuf; |
3276 | dmabuf->pbuf = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); | 3277 | dmabuf->pbuf = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); |
3277 | if(dmabuf->pbuf==NULL) | 3278 | if(dmabuf->pbuf==NULL) |
@@ -3312,10 +3313,10 @@ static int cs_open(struct inode *inode, struct file *file) | |||
3312 | state->virt = 1; | 3313 | state->virt = 1; |
3313 | state->magic = CS_STATE_MAGIC; | 3314 | state->magic = CS_STATE_MAGIC; |
3314 | init_waitqueue_head(&dmabuf->wait); | 3315 | init_waitqueue_head(&dmabuf->wait); |
3315 | init_MUTEX(&state->open_sem); | 3316 | mutex_init(&state->open_mutex); |
3316 | file->private_data = card; | 3317 | file->private_data = card; |
3317 | 3318 | ||
3318 | down(&state->open_sem); | 3319 | mutex_lock(&state->open_mutex); |
3319 | 3320 | ||
3320 | /* set default sample format. According to OSS Programmer's Guide /dev/dsp | 3321 | /* set default sample format. According to OSS Programmer's Guide /dev/dsp |
3321 | should be default to unsigned 8-bits, mono, with sample rate 8kHz and | 3322 | should be default to unsigned 8-bits, mono, with sample rate 8kHz and |
@@ -3331,7 +3332,7 @@ static int cs_open(struct inode *inode, struct file *file) | |||
3331 | cs_set_divisor(dmabuf); | 3332 | cs_set_divisor(dmabuf); |
3332 | 3333 | ||
3333 | state->open_mode |= FMODE_WRITE; | 3334 | state->open_mode |= FMODE_WRITE; |
3334 | up(&state->open_sem); | 3335 | mutex_unlock(&state->open_mutex); |
3335 | if((ret = prog_dmabuf(state))) | 3336 | if((ret = prog_dmabuf(state))) |
3336 | return ret; | 3337 | return ret; |
3337 | } | 3338 | } |
@@ -3363,14 +3364,14 @@ static int cs_release(struct inode *inode, struct file *file) | |||
3363 | cs_clear_tail(state); | 3364 | cs_clear_tail(state); |
3364 | drain_dac(state, file->f_flags & O_NONBLOCK); | 3365 | drain_dac(state, file->f_flags & O_NONBLOCK); |
3365 | /* stop DMA state machine and free DMA buffers/channels */ | 3366 | /* stop DMA state machine and free DMA buffers/channels */ |
3366 | down(&state->open_sem); | 3367 | mutex_lock(&state->open_mutex); |
3367 | stop_dac(state); | 3368 | stop_dac(state); |
3368 | dealloc_dmabuf(state); | 3369 | dealloc_dmabuf(state); |
3369 | state->card->free_pcm_channel(state->card, dmabuf->channel->num); | 3370 | state->card->free_pcm_channel(state->card, dmabuf->channel->num); |
3370 | free_page((unsigned long)state->dmabuf.pbuf); | 3371 | free_page((unsigned long)state->dmabuf.pbuf); |
3371 | 3372 | ||
3372 | /* we're covered by the open_sem */ | 3373 | /* we're covered by the open_mutex */ |
3373 | up(&state->open_sem); | 3374 | mutex_unlock(&state->open_mutex); |
3374 | state->card->states[state->virt] = NULL; | 3375 | state->card->states[state->virt] = NULL; |
3375 | state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); | 3376 | state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); |
3376 | 3377 | ||
@@ -3395,14 +3396,14 @@ static int cs_release(struct inode *inode, struct file *file) | |||
3395 | { | 3396 | { |
3396 | CS_DBGOUT(CS_RELEASE, 2, printk("cs46xx: cs_release() FMODE_READ\n") ); | 3397 | CS_DBGOUT(CS_RELEASE, 2, printk("cs46xx: cs_release() FMODE_READ\n") ); |
3397 | dmabuf = &state->dmabuf; | 3398 | dmabuf = &state->dmabuf; |
3398 | down(&state->open_sem); | 3399 | mutex_lock(&state->open_mutex); |
3399 | stop_adc(state); | 3400 | stop_adc(state); |
3400 | dealloc_dmabuf(state); | 3401 | dealloc_dmabuf(state); |
3401 | state->card->free_pcm_channel(state->card, dmabuf->channel->num); | 3402 | state->card->free_pcm_channel(state->card, dmabuf->channel->num); |
3402 | free_page((unsigned long)state->dmabuf.pbuf); | 3403 | free_page((unsigned long)state->dmabuf.pbuf); |
3403 | 3404 | ||
3404 | /* we're covered by the open_sem */ | 3405 | /* we're covered by the open_mutex */ |
3405 | up(&state->open_sem); | 3406 | mutex_unlock(&state->open_mutex); |
3406 | state->card->states[state->virt] = NULL; | 3407 | state->card->states[state->virt] = NULL; |
3407 | state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); | 3408 | state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); |
3408 | 3409 | ||
@@ -5507,7 +5508,7 @@ static int __devinit cs46xx_probe(struct pci_dev *pci_dev, | |||
5507 | } | 5508 | } |
5508 | 5509 | ||
5509 | init_waitqueue_head(&card->midi.open_wait); | 5510 | init_waitqueue_head(&card->midi.open_wait); |
5510 | init_MUTEX(&card->midi.open_sem); | 5511 | mutex_init(&card->midi.open_mutex); |
5511 | init_waitqueue_head(&card->midi.iwait); | 5512 | init_waitqueue_head(&card->midi.iwait); |
5512 | init_waitqueue_head(&card->midi.owait); | 5513 | init_waitqueue_head(&card->midi.owait); |
5513 | cs461x_pokeBA0(card, BA0_MIDCR, MIDCR_MRST); | 5514 | cs461x_pokeBA0(card, BA0_MIDCR, MIDCR_MRST); |